From e3455ce35bec43b1c5b744770a46a37a22056d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Mon, 11 Jan 2021 18:31:16 +0100 Subject: [PATCH 01/64] [APM] latencyAggregationType is not persisted when navigation to Transaction overview to detail (#87046) * persisting latency aggregation type * addressing PR comments * removing useLatencyAggregationType hook * addressing PR comments * addressing PR comments Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../ErrorGroupDetails/DetailView/index.tsx | 2 +- .../app/TraceOverview/TraceList.tsx | 2 +- .../MaybeViewTraceLink.tsx | 9 ++- .../Waterfall/FlyoutTopLevelProperties.tsx | 10 +++- .../SpanFlyout/StickySpanProperties.tsx | 13 +++-- .../service_details/service_detail_tabs.tsx | 6 +- .../service_overview.test.tsx | 7 ++- .../index.tsx | 34 +++++------ .../TransactionList/index.tsx | 9 ++- .../Links/apm/TransactionDetailLink.tsx | 49 ---------------- .../Links/apm/transaction_detail_link.tsx | 57 +++++++++++++++++++ .../apm/transaction_overview_link.test.tsx | 43 +++++++------- .../Links/apm/transaction_overview_link.tsx | 38 ++++++++++--- .../components/shared/Links/url_helpers.ts | 3 +- .../url_params_context/resolve_url_params.ts | 3 +- .../use_latency_Aggregation_type.test.ts | 46 --------------- .../hooks/use_latency_Aggregation_type.ts | 24 -------- .../use_transaction_latency_chart_fetcher.ts | 7 +-- .../selectors/latency_chart_selectors.ts | 5 +- 19 files changed, 178 insertions(+), 189 deletions(-) delete mode 100644 x-pack/plugins/apm/public/components/shared/Links/apm/TransactionDetailLink.tsx create mode 100644 x-pack/plugins/apm/public/components/shared/Links/apm/transaction_detail_link.tsx delete mode 100644 x-pack/plugins/apm/public/hooks/use_latency_Aggregation_type.test.ts delete mode 100644 x-pack/plugins/apm/public/hooks/use_latency_Aggregation_type.ts diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx index c0ce2ed388a12..57a6061cc6c98 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx @@ -24,7 +24,7 @@ import { APIReturnType } from '../../../../services/rest/createCallApmApi'; import { APMError } from '../../../../../typings/es_schemas/ui/apm_error'; import type { IUrlParams } from '../../../../context/url_params_context/types'; import { px, unit, units } from '../../../../style/variables'; -import { TransactionDetailLink } from '../../../shared/Links/apm/TransactionDetailLink'; +import { TransactionDetailLink } from '../../../shared/Links/apm/transaction_detail_link'; import { DiscoverErrorLink } from '../../../shared/Links/DiscoverLinks/DiscoverErrorLink'; import { fromQuery, toQuery } from '../../../shared/Links/url_helpers'; import { ErrorMetadata } from '../../../shared/MetadataTable/ErrorMetadata'; diff --git a/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx b/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx index eebd03772f238..b216ab5498cf6 100644 --- a/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx +++ b/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx @@ -17,7 +17,7 @@ import { EmptyMessage } from '../../shared/EmptyMessage'; import { ImpactBar } from '../../shared/ImpactBar'; import { ITableColumn, ManagedTable } from '../../shared/ManagedTable'; import { LoadingStatePrompt } from '../../shared/LoadingStatePrompt'; -import { TransactionDetailLink } from '../../shared/Links/apm/TransactionDetailLink'; +import { TransactionDetailLink } from '../../shared/Links/apm/transaction_detail_link'; import { APIReturnType } from '../../../services/rest/createCallApmApi'; type TraceGroup = APIReturnType<'GET /api/apm/traces'>['items'][0]; diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/MaybeViewTraceLink.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/MaybeViewTraceLink.tsx index 9a40d7834d18a..49a016f338888 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/MaybeViewTraceLink.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/MaybeViewTraceLink.tsx @@ -4,11 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; import { EuiButton, EuiFlexItem, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { useUrlParams } from '../../../../context/url_params_context/use_url_params'; import { Transaction as ITransaction } from '../../../../../typings/es_schemas/ui/transaction'; -import { TransactionDetailLink } from '../../../shared/Links/apm/TransactionDetailLink'; +import { TransactionDetailLink } from '../../../shared/Links/apm/transaction_detail_link'; import { IWaterfall } from './WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers'; export const MaybeViewTraceLink = ({ @@ -18,6 +19,9 @@ export const MaybeViewTraceLink = ({ transaction: ITransaction; waterfall: IWaterfall; }) => { + const { + urlParams: { latencyAggregationType }, + } = useUrlParams(); const viewFullTraceButtonLabel = i18n.translate( 'xpack.apm.transactionDetails.viewFullTraceButtonLabel', { @@ -77,6 +81,7 @@ export const MaybeViewTraceLink = ({ traceId={rootTransaction.trace.id} transactionName={rootTransaction.transaction.name} transactionType={rootTransaction.transaction.type} + latencyAggregationType={latencyAggregationType} > {viewFullTraceButtonLabel} diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/FlyoutTopLevelProperties.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/FlyoutTopLevelProperties.tsx index 0568930f8157d..a67ec0a69ed87 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/FlyoutTopLevelProperties.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/FlyoutTopLevelProperties.tsx @@ -6,20 +6,25 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; +import { useUrlParams } from '../../../../../../context/url_params_context/use_url_params'; import { SERVICE_NAME, TRANSACTION_NAME, } from '../../../../../../../common/elasticsearch_fieldnames'; import { Transaction } from '../../../../../../../typings/es_schemas/ui/transaction'; -import { TransactionDetailLink } from '../../../../../shared/Links/apm/TransactionDetailLink'; -import { StickyProperties } from '../../../../../shared/StickyProperties'; import { ServiceOrTransactionsOverviewLink } from '../../../../../shared/Links/apm/service_transactions_overview_link'; +import { TransactionDetailLink } from '../../../../../shared/Links/apm/transaction_detail_link'; +import { StickyProperties } from '../../../../../shared/StickyProperties'; interface Props { transaction?: Transaction; } export function FlyoutTopLevelProperties({ transaction }: Props) { + const { + urlParams: { latencyAggregationType }, + } = useUrlParams(); + if (!transaction) { return null; } @@ -51,6 +56,7 @@ export function FlyoutTopLevelProperties({ transaction }: Props) { traceId={transaction.trace.id} transactionName={transaction.transaction.name} transactionType={transaction.transaction.type} + latencyAggregationType={latencyAggregationType} > {transaction.transaction.name} diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/SpanFlyout/StickySpanProperties.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/SpanFlyout/StickySpanProperties.tsx index 6bcb9a764a352..5a1f6e3d2a24d 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/SpanFlyout/StickySpanProperties.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/SpanFlyout/StickySpanProperties.tsx @@ -6,17 +6,18 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; -import { Transaction } from '../../../../../../../../typings/es_schemas/ui/transaction'; +import { useUrlParams } from '../../../../../../../context/url_params_context/use_url_params'; import { + SERVICE_NAME, SPAN_NAME, TRANSACTION_NAME, - SERVICE_NAME, } from '../../../../../../../../common/elasticsearch_fieldnames'; import { NOT_AVAILABLE_LABEL } from '../../../../../../../../common/i18n'; import { Span } from '../../../../../../../../typings/es_schemas/ui/span'; -import { StickyProperties } from '../../../../../../shared/StickyProperties'; +import { Transaction } from '../../../../../../../../typings/es_schemas/ui/transaction'; import { ServiceOrTransactionsOverviewLink } from '../../../../../../shared/Links/apm/service_transactions_overview_link'; -import { TransactionDetailLink } from '../../../../../../shared/Links/apm/TransactionDetailLink'; +import { TransactionDetailLink } from '../../../../../../shared/Links/apm/transaction_detail_link'; +import { StickyProperties } from '../../../../../../shared/StickyProperties'; interface Props { span: Span; @@ -24,6 +25,9 @@ interface Props { } export function StickySpanProperties({ span, transaction }: Props) { + const { + urlParams: { latencyAggregationType }, + } = useUrlParams(); const spanName = span.span.name; const transactionStickyProperties = transaction ? [ @@ -56,6 +60,7 @@ export function StickySpanProperties({ span, transaction }: Props) { traceId={transaction.trace.id} transactionName={transaction.transaction.name} transactionType={transaction.transaction.type} + latencyAggregationType={latencyAggregationType} > {transaction.transaction.name} diff --git a/x-pack/plugins/apm/public/components/app/service_details/service_detail_tabs.tsx b/x-pack/plugins/apm/public/components/app/service_details/service_detail_tabs.tsx index 958d25a88434c..fe3cb541617a3 100644 --- a/x-pack/plugins/apm/public/components/app/service_details/service_detail_tabs.tsx +++ b/x-pack/plugins/apm/public/components/app/service_details/service_detail_tabs.tsx @@ -11,6 +11,7 @@ import { isJavaAgentName, isRumAgentName } from '../../../../common/agent_name'; import { enableServiceOverview } from '../../../../common/ui_settings_keys'; import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context'; import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context'; +import { useUrlParams } from '../../../context/url_params_context/use_url_params'; import { useErrorOverviewHref } from '../../shared/Links/apm/ErrorOverviewLink'; import { useMetricOverviewHref } from '../../shared/Links/apm/MetricOverviewLink'; import { useServiceMapHref } from '../../shared/Links/apm/ServiceMapLink'; @@ -46,6 +47,9 @@ interface Props { export function ServiceDetailTabs({ serviceName, tab }: Props) { const { agentName } = useApmServiceContext(); const { uiSettings } = useApmPluginContext().core; + const { + urlParams: { latencyAggregationType }, + } = useUrlParams(); const overviewTab = { key: 'overview', @@ -60,7 +64,7 @@ export function ServiceDetailTabs({ serviceName, tab }: Props) { const transactionsTab = { key: 'transactions', - href: useTransactionsOverviewHref(serviceName), + href: useTransactionsOverviewHref({ serviceName, latencyAggregationType }), text: i18n.translate('xpack.apm.serviceDetails.transactionsTabLabel', { defaultMessage: 'Transactions', }), diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview.test.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview.test.tsx index c02f72245cdf5..46c2a4c322c92 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview.test.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview.test.tsx @@ -23,6 +23,7 @@ import { ServiceOverview } from './'; import { waitFor } from '@testing-library/dom'; import * as callApmApiModule from '../../../services/rest/createCallApmApi'; import * as useApmServiceContextHooks from '../../../context/apm_service/use_apm_service_context'; +import { LatencyAggregationType } from '../../../../common/latency_aggregation_types'; const KibanaReactContext = createKibanaReactContext({ usageCollection: { reportUiCounter: () => {} }, @@ -45,7 +46,11 @@ function Wrapper({ children }: { children?: ReactNode }) { {children} diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_transactions_table/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_transactions_table/index.tsx index 7c90ea68d6f84..307997731e5ef 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_transactions_table/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_transactions_table/index.tsx @@ -23,7 +23,6 @@ import { import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context'; import { useUrlParams } from '../../../../context/url_params_context/use_url_params'; import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher'; -import { useLatencyAggregationType } from '../../../../hooks/use_latency_Aggregation_type'; import { APIReturnType, callApmApi, @@ -31,7 +30,7 @@ import { import { px, unit } from '../../../../style/variables'; import { SparkPlot } from '../../../shared/charts/spark_plot'; import { ImpactBar } from '../../../shared/ImpactBar'; -import { TransactionDetailLink } from '../../../shared/Links/apm/TransactionDetailLink'; +import { TransactionDetailLink } from '../../../shared/Links/apm/transaction_detail_link'; import { TransactionOverviewLink } from '../../../shared/Links/apm/transaction_overview_link'; import { TableFetchWrapper } from '../../../shared/table_fetch_wrapper'; import { TruncateWithTooltip } from '../../../shared/truncate_with_tooltip'; @@ -54,10 +53,16 @@ const DEFAULT_SORT = { field: 'impact' as const, }; -function getLatencyAggregationTypeLabel( - latencyAggregationType?: LatencyAggregationType -) { +function getLatencyAggregationTypeLabel(latencyAggregationType?: string) { switch (latencyAggregationType) { + case 'avg': { + i18n.translate( + 'xpack.apm.serviceOverview.transactionsTableColumnLatency.avg', + { + defaultMessage: 'Latency (avg.)', + } + ); + } case 'p95': { return i18n.translate( 'xpack.apm.serviceOverview.transactionsTableColumnLatency.p95', @@ -74,24 +79,15 @@ function getLatencyAggregationTypeLabel( } ); } - default: { - return i18n.translate( - 'xpack.apm.serviceOverview.transactionsTableColumnLatency.avg', - { - defaultMessage: 'Latency (avg.)', - } - ); - } } } export function ServiceOverviewTransactionsTable(props: Props) { const { serviceName } = props; const { transactionType } = useApmServiceContext(); - const latencyAggregationType = useLatencyAggregationType(); const { uiFilters, - urlParams: { start, end }, + urlParams: { start, end, latencyAggregationType }, } = useUrlParams(); const [tableOptions, setTableOptions] = useState<{ @@ -135,7 +131,7 @@ export function ServiceOverviewTransactionsTable(props: Props) { sortField: tableOptions.sort.field, sortDirection: tableOptions.sort.direction, transactionType, - latencyAggregationType, + latencyAggregationType: latencyAggregationType as LatencyAggregationType, }, }, }).then((response) => { @@ -187,6 +183,7 @@ export function ServiceOverviewTransactionsTable(props: Props) { serviceName={serviceName} transactionName={name} transactionType={type} + latencyAggregationType={latencyAggregationType} > {name} @@ -282,7 +279,10 @@ export function ServiceOverviewTransactionsTable(props: Props) { - + {i18n.translate( 'xpack.apm.serviceOverview.transactionsTableLinkText', { diff --git a/x-pack/plugins/apm/public/components/app/transaction_overview/TransactionList/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_overview/TransactionList/index.tsx index ade0a0563b0dc..1699b7e7474fe 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_overview/TransactionList/index.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_overview/TransactionList/index.tsx @@ -8,6 +8,7 @@ import { EuiToolTip, EuiIconTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useMemo } from 'react'; import styled from 'styled-components'; +import { useUrlParams } from '../../../../context/url_params_context/use_url_params'; import { APIReturnType } from '../../../../services/rest/createCallApmApi'; import { asMillisecondDuration, @@ -18,7 +19,7 @@ import { ImpactBar } from '../../../shared/ImpactBar'; import { ITableColumn, ManagedTable } from '../../../shared/ManagedTable'; import { LoadingStatePrompt } from '../../../shared/LoadingStatePrompt'; import { EmptyMessage } from '../../../shared/EmptyMessage'; -import { TransactionDetailLink } from '../../../shared/Links/apm/TransactionDetailLink'; +import { TransactionDetailLink } from '../../../shared/Links/apm/transaction_detail_link'; type TransactionGroup = APIReturnType<'GET /api/apm/services/{serviceName}/transactions/groups'>['items'][0]; @@ -40,6 +41,9 @@ interface Props { } export function TransactionList({ items, isLoading }: Props) { + const { + urlParams: { latencyAggregationType }, + } = useUrlParams(); const columns: Array> = useMemo( () => [ { @@ -58,6 +62,7 @@ export function TransactionList({ items, isLoading }: Props) { serviceName={serviceName} transactionName={transactionName} transactionType={transactionType} + latencyAggregationType={latencyAggregationType} > , }, ], - [] + [latencyAggregationType] ); const noItemsMessage = ( diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/TransactionDetailLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/TransactionDetailLink.tsx deleted file mode 100644 index ee798e0208c2b..0000000000000 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/TransactionDetailLink.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { APMLink, APMLinkExtendProps } from './APMLink'; -import { useUrlParams } from '../../../../context/url_params_context/use_url_params'; -import { pickKeys } from '../../../../../common/utils/pick_keys'; - -interface Props extends APMLinkExtendProps { - serviceName: string; - traceId?: string; - transactionId?: string; - transactionName: string; - transactionType: string; -} - -export function TransactionDetailLink({ - serviceName, - traceId, - transactionId, - transactionName, - transactionType, - ...rest -}: Props) { - const { urlParams } = useUrlParams(); - - const persistedFilters = pickKeys( - urlParams, - 'transactionResult', - 'serviceVersion' - ); - - return ( - - ); -} diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_detail_link.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_detail_link.tsx new file mode 100644 index 0000000000000..8108dcf41321f --- /dev/null +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_detail_link.tsx @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { useLocation } from 'react-router-dom'; +import { EuiLink } from '@elastic/eui'; +import { getAPMHref, APMLinkExtendProps } from './APMLink'; +import { useUrlParams } from '../../../../context/url_params_context/use_url_params'; +import { pickKeys } from '../../../../../common/utils/pick_keys'; +import { APMQueryParams } from '../url_helpers'; +import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context'; + +interface Props extends APMLinkExtendProps { + serviceName: string; + traceId?: string; + transactionId?: string; + transactionName: string; + transactionType: string; + latencyAggregationType?: string; +} + +const persistedFilters: Array = [ + 'transactionResult', + 'serviceVersion', +]; + +export function TransactionDetailLink({ + serviceName, + traceId, + transactionId, + transactionName, + transactionType, + latencyAggregationType, + ...rest +}: Props) { + const { urlParams } = useUrlParams(); + const { core } = useApmPluginContext(); + const location = useLocation(); + const href = getAPMHref({ + basePath: core.http.basePath, + path: `/services/${serviceName}/transactions/view`, + query: { + traceId, + transactionId, + transactionName, + transactionType, + ...(latencyAggregationType ? { latencyAggregationType } : {}), + ...pickKeys(urlParams as APMQueryParams, ...persistedFilters), + }, + search: location.search, + }); + + return ; +} diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.test.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.test.tsx index 3ab6feaf5ae12..5ca94884462db 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.test.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.test.tsx @@ -17,13 +17,11 @@ import { const history = createMemoryHistory(); -function wrapper({ queryParams }: { queryParams?: Record }) { - return ({ children }: { children: React.ReactElement }) => ( +function Wrapper({ children }: { children: React.ReactElement }) { + return ( - - {children} - + {children} ); @@ -32,18 +30,24 @@ function wrapper({ queryParams }: { queryParams?: Record }) { describe('Transactions overview link', () => { describe('useTransactionsOverviewHref', () => { it('returns transaction link', () => { - const { result } = renderHook(() => useTransactionsOverviewHref('foo'), { - wrapper: wrapper({}), - }); + const { result } = renderHook( + () => useTransactionsOverviewHref({ serviceName: 'foo' }), + { wrapper: Wrapper } + ); expect(result.current).toEqual( '/basepath/app/apm/services/foo/transactions' ); }); it('returns transaction link with persisted query items', () => { - const { result } = renderHook(() => useTransactionsOverviewHref('foo'), { - wrapper: wrapper({ queryParams: { latencyAggregationType: 'avg' } }), - }); + const { result } = renderHook( + () => + useTransactionsOverviewHref({ + serviceName: 'foo', + latencyAggregationType: 'avg', + }), + { wrapper: Wrapper } + ); expect(result.current).toEqual( '/basepath/app/apm/services/foo/transactions?latencyAggregationType=avg' ); @@ -55,13 +59,12 @@ describe('Transactions overview link', () => { .href; } it('returns transaction link', () => { - const Component = wrapper({}); const { container } = render( - + Service name - + ); expect(getHref(container)).toEqual( 'http://localhost/basepath/app/apm/services/foo/transactions' @@ -69,15 +72,15 @@ describe('Transactions overview link', () => { }); it('returns transaction link with persisted query items', () => { - const Component = wrapper({ - queryParams: { latencyAggregationType: 'avg' }, - }); const { container } = render( - - + + Service name - + ); expect(getHref(container)).toEqual( 'http://localhost/basepath/app/apm/services/foo/transactions?latencyAggregationType=avg' diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.tsx index cd6d70b2e2e6d..dd53c5ab15260 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.tsx @@ -6,22 +6,42 @@ import { EuiLink } from '@elastic/eui'; import React from 'react'; -import { APMQueryParams } from '../url_helpers'; -import { APMLinkExtendProps, useAPMHref } from './APMLink'; +import { useLocation } from 'react-router-dom'; +import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context'; +import { APMLinkExtendProps, getAPMHref } from './APMLink'; interface Props extends APMLinkExtendProps { serviceName: string; + latencyAggregationType?: string; } -const persistedFilters: Array = [ - 'latencyAggregationType', -]; +export function useTransactionsOverviewHref({ + serviceName, + latencyAggregationType, +}: { + serviceName: string; + latencyAggregationType?: string; +}) { + const { core } = useApmPluginContext(); + const location = useLocation(); + const { search } = location; -export function useTransactionsOverviewHref(serviceName: string) { - return useAPMHref(`/services/${serviceName}/transactions`, persistedFilters); + return getAPMHref({ + basePath: core.http.basePath, + path: `/services/${serviceName}/transactions`, + query: { ...(latencyAggregationType ? { latencyAggregationType } : {}) }, + search, + }); } -export function TransactionOverviewLink({ serviceName, ...rest }: Props) { - const href = useTransactionsOverviewHref(serviceName); +export function TransactionOverviewLink({ + serviceName, + latencyAggregationType, + ...rest +}: Props) { + const href = useTransactionsOverviewHref({ + serviceName, + latencyAggregationType, + }); return ; } diff --git a/x-pack/plugins/apm/public/components/shared/Links/url_helpers.ts b/x-pack/plugins/apm/public/components/shared/Links/url_helpers.ts index aa3881b81cc3f..8576d9ee86353 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/url_helpers.ts +++ b/x-pack/plugins/apm/public/components/shared/Links/url_helpers.ts @@ -6,7 +6,6 @@ import { History } from 'history'; import { parse, stringify } from 'query-string'; -import { LatencyAggregationType } from '../../../../common/latency_aggregation_types'; import { url } from '../../../../../../../src/plugins/kibana_utils/public'; import { LocalUIFilterName } from '../../../../common/ui_filter'; @@ -85,7 +84,7 @@ export type APMQueryParams = { refreshInterval?: string | number; searchTerm?: string; percentile?: 50 | 75 | 90 | 95 | 99; - latencyAggregationType?: LatencyAggregationType; + latencyAggregationType?: string; } & { [key in LocalUIFilterName]?: string }; // forces every value of T[K] to be type: string diff --git a/x-pack/plugins/apm/public/context/url_params_context/resolve_url_params.ts b/x-pack/plugins/apm/public/context/url_params_context/resolve_url_params.ts index ee0ea7f601f62..6d9f982f92751 100644 --- a/x-pack/plugins/apm/public/context/url_params_context/resolve_url_params.ts +++ b/x-pack/plugins/apm/public/context/url_params_context/resolve_url_params.ts @@ -5,6 +5,7 @@ */ import { Location } from 'history'; +import { LatencyAggregationType } from '../../../common/latency_aggregation_types'; import { pickKeys } from '../../../common/utils/pick_keys'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { localUIFilterNames } from '../../../server/lib/ui_filters/local_ui_filters/config'; @@ -48,7 +49,7 @@ export function resolveUrlParams(location: Location, state: TimeUrlParams) { environment, searchTerm, percentile, - latencyAggregationType, + latencyAggregationType = LatencyAggregationType.avg, } = query; const localUIFilters = pickKeys(query, ...localUIFilterNames); diff --git a/x-pack/plugins/apm/public/hooks/use_latency_Aggregation_type.test.ts b/x-pack/plugins/apm/public/hooks/use_latency_Aggregation_type.test.ts deleted file mode 100644 index 901877ca67460..0000000000000 --- a/x-pack/plugins/apm/public/hooks/use_latency_Aggregation_type.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { LatencyAggregationType } from '../../common/latency_aggregation_types'; -import { UIFilters } from '../../typings/ui_filters'; -import { IUrlParams } from '../context/url_params_context/types'; -import * as urlParams from '../context/url_params_context/use_url_params'; -import { useLatencyAggregationType } from './use_latency_Aggregation_type'; - -describe('useLatencyAggregationType', () => { - afterAll(() => { - jest.clearAllMocks(); - }); - it('returns avg when no value was given', () => { - jest.spyOn(urlParams, 'useUrlParams').mockReturnValue({ - urlParams: { latencyAggregationType: undefined } as IUrlParams, - refreshTimeRange: jest.fn(), - uiFilters: {} as UIFilters, - }); - const latencyAggregationType = useLatencyAggregationType(); - expect(latencyAggregationType).toEqual(LatencyAggregationType.avg); - }); - - it('returns avg when no value does not match any of the availabe options', () => { - jest.spyOn(urlParams, 'useUrlParams').mockReturnValue({ - urlParams: { latencyAggregationType: 'invalid_type' } as IUrlParams, - refreshTimeRange: jest.fn(), - uiFilters: {} as UIFilters, - }); - const latencyAggregationType = useLatencyAggregationType(); - expect(latencyAggregationType).toEqual(LatencyAggregationType.avg); - }); - - it('returns the value in the url', () => { - jest.spyOn(urlParams, 'useUrlParams').mockReturnValue({ - urlParams: { latencyAggregationType: 'p95' } as IUrlParams, - refreshTimeRange: jest.fn(), - uiFilters: {} as UIFilters, - }); - const latencyAggregationType = useLatencyAggregationType(); - expect(latencyAggregationType).toEqual(LatencyAggregationType.p95); - }); -}); diff --git a/x-pack/plugins/apm/public/hooks/use_latency_Aggregation_type.ts b/x-pack/plugins/apm/public/hooks/use_latency_Aggregation_type.ts deleted file mode 100644 index 72d07c9e4c22c..0000000000000 --- a/x-pack/plugins/apm/public/hooks/use_latency_Aggregation_type.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { LatencyAggregationType } from '../../common/latency_aggregation_types'; -import { useUrlParams } from '../context/url_params_context/use_url_params'; - -export function useLatencyAggregationType(): LatencyAggregationType { - const { - urlParams: { latencyAggregationType }, - } = useUrlParams(); - - if (!latencyAggregationType) { - return LatencyAggregationType.avg; - } - - if (latencyAggregationType in LatencyAggregationType) { - return latencyAggregationType as LatencyAggregationType; - } - - return LatencyAggregationType.avg; -} diff --git a/x-pack/plugins/apm/public/hooks/use_transaction_latency_chart_fetcher.ts b/x-pack/plugins/apm/public/hooks/use_transaction_latency_chart_fetcher.ts index 7b1e7b06ac283..de3e68620b6e4 100644 --- a/x-pack/plugins/apm/public/hooks/use_transaction_latency_chart_fetcher.ts +++ b/x-pack/plugins/apm/public/hooks/use_transaction_latency_chart_fetcher.ts @@ -11,15 +11,14 @@ import { useUrlParams } from '../context/url_params_context/use_url_params'; import { useApmServiceContext } from '../context/apm_service/use_apm_service_context'; import { getLatencyChartSelector } from '../selectors/latency_chart_selectors'; import { useTheme } from './use_theme'; -import { useLatencyAggregationType } from './use_latency_Aggregation_type'; +import { LatencyAggregationType } from '../../common/latency_aggregation_types'; export function useTransactionLatencyChartsFetcher() { const { serviceName } = useParams<{ serviceName?: string }>(); const { transactionType } = useApmServiceContext(); - const latencyAggregationType = useLatencyAggregationType(); const theme = useTheme(); const { - urlParams: { start, end, transactionName }, + urlParams: { start, end, transactionName, latencyAggregationType }, uiFilters, } = useUrlParams(); @@ -43,7 +42,7 @@ export function useTransactionLatencyChartsFetcher() { transactionType, transactionName, uiFilters: JSON.stringify(uiFilters), - latencyAggregationType, + latencyAggregationType: latencyAggregationType as LatencyAggregationType, }, }, }); diff --git a/x-pack/plugins/apm/public/selectors/latency_chart_selectors.ts b/x-pack/plugins/apm/public/selectors/latency_chart_selectors.ts index dee92bbffd27a..a5c25cfa3e07c 100644 --- a/x-pack/plugins/apm/public/selectors/latency_chart_selectors.ts +++ b/x-pack/plugins/apm/public/selectors/latency_chart_selectors.ts @@ -6,7 +6,6 @@ import { i18n } from '@kbn/i18n'; import { rgba } from 'polished'; import { EuiTheme } from '../../../observability/public'; -import { LatencyAggregationType } from '../../common/latency_aggregation_types'; import { asDuration } from '../../common/utils/formatters'; import { Coordinate, @@ -33,7 +32,7 @@ export function getLatencyChartSelector({ }: { latencyChart?: LatencyChartsResponse; theme: EuiTheme; - latencyAggregationType?: LatencyAggregationType; + latencyAggregationType?: string; }): LatencyChart { if (!latencyChart?.latencyTimeseries || !latencyAggregationType) { return { @@ -63,7 +62,7 @@ function getLatencyTimeseries({ }: { latencyChart: LatencyChartsResponse; theme: EuiTheme; - latencyAggregationType: LatencyAggregationType; + latencyAggregationType: string; }) { const { overallAvgDuration } = latencyChart; const { latencyTimeseries } = latencyChart; From 61987df922fe68161a2e682241fd8bdeda86f40d Mon Sep 17 00:00:00 2001 From: Sandra Gonzales Date: Mon, 11 Jan 2021 12:35:11 -0500 Subject: [PATCH 02/64] [Fleet] use package storage when getting a package (#85337) * getPackageFromSource to use package storage * fix type * use bulkGet * add data streams and policy templates to package info from storage * fix merge conflict * comment out policy_templates for now * add policy_templates to package info, remove required inputs from parseAndVerifyPolicyTemplates * add storage assets to cache * tidy up Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../server/services/epm/archive/cache.ts | 1 + .../server/services/epm/archive/storage.ts | 115 +++++++++++++++++- .../server/services/epm/archive/validation.ts | 25 ++-- .../epm/kibana/index_pattern/install.ts | 25 ++-- .../fleet/server/services/epm/packages/get.ts | 64 ++++++---- .../server/services/epm/registry/index.ts | 1 - 6 files changed, 186 insertions(+), 45 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/epm/archive/cache.ts b/x-pack/plugins/fleet/server/services/epm/archive/cache.ts index 6032159fdfcc5..13d58f0c75763 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/cache.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/cache.ts @@ -39,6 +39,7 @@ export const getPackageInfo = (args: SharedKey) => { export const getArchivePackage = (args: SharedKey) => { const packageInfo = getPackageInfo(args); const paths = getArchiveFilelist(args); + if (!paths || !packageInfo) return undefined; return { paths, packageInfo, diff --git a/x-pack/plugins/fleet/server/services/epm/archive/storage.ts b/x-pack/plugins/fleet/server/services/epm/archive/storage.ts index f7323279e0e7c..02e7e33421737 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/storage.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/storage.ts @@ -5,6 +5,8 @@ */ import { extname } from 'path'; +import { uniq } from 'lodash'; +import { safeLoad } from 'js-yaml'; import { isBinaryFile } from 'isbinaryfile'; import mime from 'mime-types'; import uuidv5 from 'uuid/v5'; @@ -14,8 +16,11 @@ import { InstallablePackage, InstallSource, PackageAssetReference, + RegistryDataStream, } from '../../../../common'; -import { getArchiveEntry } from './index'; +import { ArchiveEntry, getArchiveEntry, setArchiveEntry, setArchiveFilelist } from './index'; +import { parseAndVerifyPolicyTemplates, parseAndVerifyStreams } from './validation'; +import { pkgToPkgKey } from '../registry'; // could be anything, picked this from https://github.com/elastic/elastic-agent-client/issues/17 const MAX_ES_ASSET_BYTES = 4 * 1024 * 1024; @@ -121,6 +126,15 @@ export async function archiveEntryToBulkCreateObject(opts: { attributes: doc, }; } +export function packageAssetToArchiveEntry(asset: PackageAsset): ArchiveEntry { + const { asset_path: path, data_utf8: utf8, data_base64: base64 } = asset; + const buffer = utf8 ? Buffer.from(utf8, 'utf8') : Buffer.from(base64, 'base64'); + + return { + path, + buffer, + }; +} export async function getAsset(opts: { savedObjectsClient: SavedObjectsClientContract; @@ -138,3 +152,102 @@ export async function getAsset(opts: { return storedAsset; } + +export const getEsPackage = async ( + pkgName: string, + pkgVersion: string, + references: PackageAssetReference[], + savedObjectsClient: SavedObjectsClientContract +) => { + const pkgKey = pkgToPkgKey({ name: pkgName, version: pkgVersion }); + const bulkRes = await savedObjectsClient.bulkGet( + references.map((reference) => ({ + ...reference, + fields: ['asset_path', 'data_utf8', 'data_base64'], + })) + ); + const assets = bulkRes.saved_objects.map((so) => so.attributes); + + // add asset references to cache + const paths: string[] = []; + const entries: ArchiveEntry[] = assets.map(packageAssetToArchiveEntry); + entries.forEach(({ path, buffer }) => { + if (path && buffer) { + setArchiveEntry(path, buffer); + paths.push(path); + } + }); + setArchiveFilelist({ name: pkgName, version: pkgVersion }, paths); + // create the packageInfo + // TODO: this is mostly copied from validtion.ts, needed in case package does not exist in storage yet or is missing from cache + // we don't want to reach out to the registry again so recreate it here. should check whether it exists in packageInfoCache first + + const manifestPath = `${pkgName}-${pkgVersion}/manifest.yml`; + const soResManifest = await savedObjectsClient.get( + ASSETS_SAVED_OBJECT_TYPE, + assetPathToObjectId(manifestPath) + ); + const packageInfo = safeLoad(soResManifest.attributes.data_utf8); + + try { + const readmePath = `docs/README.md`; + await savedObjectsClient.get( + ASSETS_SAVED_OBJECT_TYPE, + assetPathToObjectId(`${pkgName}-${pkgVersion}/${readmePath}`) + ); + packageInfo.readme = `/package/${pkgName}/${pkgVersion}/${readmePath}`; + } catch (err) { + // read me doesn't exist + } + + let dataStreamPaths: string[] = []; + const dataStreams: RegistryDataStream[] = []; + paths + .filter((path) => path.startsWith(`${pkgKey}/data_stream/`)) + .forEach((path) => { + const parts = path.split('/'); + if (parts.length > 2 && parts[2]) dataStreamPaths.push(parts[2]); + }); + + dataStreamPaths = uniq(dataStreamPaths); + + await Promise.all( + dataStreamPaths.map(async (dataStreamPath) => { + const dataStreamManifestPath = `${pkgKey}/data_stream/${dataStreamPath}/manifest.yml`; + const soResDataStreamManifest = await savedObjectsClient.get( + ASSETS_SAVED_OBJECT_TYPE, + assetPathToObjectId(dataStreamManifestPath) + ); + const dataStreamManifest = safeLoad(soResDataStreamManifest.attributes.data_utf8); + const { + title: dataStreamTitle, + release, + ingest_pipeline: ingestPipeline, + type, + dataset, + } = dataStreamManifest; + const streams = parseAndVerifyStreams(dataStreamManifest, dataStreamPath); + + dataStreams.push({ + dataset: dataset || `${pkgName}.${dataStreamPath}`, + title: dataStreamTitle, + release, + package: pkgName, + ingest_pipeline: ingestPipeline || 'default', + path: dataStreamPath, + type, + streams, + }); + }) + ); + packageInfo.policy_templates = parseAndVerifyPolicyTemplates(packageInfo); + packageInfo.data_streams = dataStreams; + packageInfo.assets = paths.map((path) => { + return path.replace(`${pkgName}-${pkgVersion}`, `/package/${pkgName}/${pkgVersion}`); + }); + + return { + paths, + packageInfo, + }; +}; diff --git a/x-pack/plugins/fleet/server/services/epm/archive/validation.ts b/x-pack/plugins/fleet/server/services/epm/archive/validation.ts index cf5e7ae0f063c..60ba80fb45f9a 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/validation.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/validation.ts @@ -13,6 +13,7 @@ import { RegistryInput, RegistryStream, RegistryVarsEntry, + PackageSpecManifest, } from '../../../../common/types'; import { PackageInvalidArchiveError } from '../../../errors'; import { unpackBufferEntries } from './index'; @@ -143,7 +144,7 @@ function parseAndVerifyReadme(paths: string[], pkgName: string, pkgVersion: stri const readmePath = `${pkgName}-${pkgVersion}${readmeRelPath}`; return paths.includes(readmePath) ? `/package/${pkgName}/${pkgVersion}${readmeRelPath}` : null; } -function parseAndVerifyDataStreams( +export function parseAndVerifyDataStreams( paths: string[], pkgName: string, pkgVersion: string @@ -211,7 +212,7 @@ function parseAndVerifyDataStreams( return dataStreams; } -function parseAndVerifyStreams(manifest: any, dataStreamPath: string): RegistryStream[] { +export function parseAndVerifyStreams(manifest: any, dataStreamPath: string): RegistryStream[] { const streams: RegistryStream[] = []; const manifestStreams = manifest.streams; if (manifestStreams && manifestStreams.length > 0) { @@ -243,7 +244,7 @@ function parseAndVerifyStreams(manifest: any, dataStreamPath: string): RegistryS } return streams; } -function parseAndVerifyVars(manifestVars: any[], location: string): RegistryVarsEntry[] { +export function parseAndVerifyVars(manifestVars: any[], location: string): RegistryVarsEntry[] { const vars: RegistryVarsEntry[] = []; if (manifestVars && manifestVars.length > 0) { manifestVars.forEach((manifestVar) => { @@ -278,19 +279,23 @@ function parseAndVerifyVars(manifestVars: any[], location: string): RegistryVars } return vars; } -function parseAndVerifyPolicyTemplates(manifest: any): RegistryPolicyTemplate[] { +export function parseAndVerifyPolicyTemplates( + manifest: PackageSpecManifest +): RegistryPolicyTemplate[] { const policyTemplates: RegistryPolicyTemplate[] = []; const manifestPolicyTemplates = manifest.policy_templates; - if (manifestPolicyTemplates && manifestPolicyTemplates > 0) { + if (manifestPolicyTemplates && manifestPolicyTemplates.length > 0) { manifestPolicyTemplates.forEach((policyTemplate: any) => { const { name, title: policyTemplateTitle, description, inputs, multiple } = policyTemplate; - if (!(name && policyTemplateTitle && description && inputs)) { + if (!(name && policyTemplateTitle && description)) { throw new PackageInvalidArchiveError( - `Invalid top-level manifest: one of mandatory fields 'name', 'title', 'description', 'input' missing in policy template: ${policyTemplate}` + `Invalid top-level manifest: one of mandatory fields 'name', 'title', 'description' is missing in policy template: ${policyTemplate}` ); } - - const parsedInputs = parseAndVerifyInputs(inputs, `config template ${name}`); + let parsedInputs: RegistryInput[] | undefined = []; + if (inputs) { + parsedInputs = parseAndVerifyInputs(inputs, `config template ${name}`); + } // defaults to true if undefined, but may be explicitly set to false. let parsedMultiple = true; @@ -307,7 +312,7 @@ function parseAndVerifyPolicyTemplates(manifest: any): RegistryPolicyTemplate[] } return policyTemplates; } -function parseAndVerifyInputs(manifestInputs: any, location: string): RegistryInput[] { +export function parseAndVerifyInputs(manifestInputs: any, location: string): RegistryInput[] { const inputs: RegistryInput[] = []; if (manifestInputs && manifestInputs.length > 0) { manifestInputs.forEach((input: any) => { diff --git a/x-pack/plugins/fleet/server/services/epm/kibana/index_pattern/install.ts b/x-pack/plugins/fleet/server/services/epm/kibana/index_pattern/install.ts index d5077308a5301..94fa4b58cd1b8 100644 --- a/x-pack/plugins/fleet/server/services/epm/kibana/index_pattern/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/kibana/index_pattern/install.ts @@ -8,9 +8,9 @@ import { SavedObjectsClientContract } from 'src/core/server'; import { INDEX_PATTERN_SAVED_OBJECT_TYPE } from '../../../../constants'; import { loadFieldsFromYaml, Fields, Field } from '../../fields/field'; import { dataTypes, installationStatuses } from '../../../../../common/constants'; -import { ArchivePackage, InstallSource, ValueOf } from '../../../../../common/types'; +import { ArchivePackage, Installation, InstallSource, ValueOf } from '../../../../../common/types'; import { RegistryPackage, DataType } from '../../../../types'; -import { getPackageFromSource, getPackageSavedObjects } from '../../packages/get'; +import { getInstallation, getPackageFromSource, getPackageSavedObjects } from '../../packages/get'; interface FieldFormatMap { [key: string]: FieldFormatMapItem; @@ -81,18 +81,18 @@ export async function installIndexPatterns( ); const packagesToFetch = installedPackagesSavedObjects.reduce< - Array<{ name: string; version: string; installSource: InstallSource }> - >((acc, pkgSO) => { + Array<{ name: string; version: string; installedPkg: Installation | undefined }> + >((acc, pkg) => { acc.push({ - name: pkgSO.attributes.name, - version: pkgSO.attributes.version, - installSource: pkgSO.attributes.install_source, + name: pkg.attributes.name, + version: pkg.attributes.version, + installedPkg: pkg.attributes, }); return acc; }, []); if (pkgName && pkgVersion && installSource) { - const packageToInstall = packagesToFetch.find((pkgSO) => pkgSO.name === pkgName); + const packageToInstall = packagesToFetch.find((pkg) => pkg.name === pkgName); if (packageToInstall) { // set the version to the one we want to install // if we're reinstalling the number will be the same @@ -100,7 +100,11 @@ export async function installIndexPatterns( packageToInstall.version = pkgVersion; } else { // if we're installing for the first time, add to the list - packagesToFetch.push({ name: pkgName, version: pkgVersion, installSource }); + packagesToFetch.push({ + name: pkgName, + version: pkgVersion, + installedPkg: await getInstallation({ savedObjectsClient, pkgName }), + }); } } // get each package's registry info @@ -108,7 +112,8 @@ export async function installIndexPatterns( getPackageFromSource({ pkgName: pkg.name, pkgVersion: pkg.version, - pkgInstallSource: pkg.installSource, + installedPkg: pkg.installedPkg, + savedObjectsClient, }) ); const packages = await Promise.all(packagesToFetchPromise); diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get.ts b/x-pack/plugins/fleet/server/services/epm/packages/get.ts index 01aaf111fef84..f59b7a8484035 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/get.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/get.ts @@ -7,15 +7,11 @@ import { SavedObjectsClientContract, SavedObjectsFindOptions } from 'src/core/server'; import { isPackageLimited, installationStatuses } from '../../../../common'; import { PACKAGES_SAVED_OBJECT_TYPE } from '../../../constants'; -import { - ArchivePackage, - InstallSource, - RegistryPackage, - EpmPackageAdditions, -} from '../../../../common/types'; +import { ArchivePackage, RegistryPackage, EpmPackageAdditions } from '../../../../common/types'; import { Installation, PackageInfo, KibanaAssetType } from '../../../types'; import * as Registry from '../registry'; import { createInstallableFrom, isRequiredPackage } from './index'; +import { getEsPackage } from '../archive/storage'; import { getArchivePackage } from '../archive'; export { getFile, SearchParams } from '../registry'; @@ -103,13 +99,10 @@ export async function getPackageInfo(options: { const getPackageRes = await getPackageFromSource({ pkgName, pkgVersion, - pkgInstallSource: - savedObject?.attributes.version === pkgVersion - ? savedObject?.attributes.install_source - : 'registry', + savedObjectsClient, + installedPkg: savedObject?.attributes, }); - const paths = getPackageRes.paths; - const packageInfo = getPackageRes.packageInfo; + const { paths, packageInfo } = getPackageRes; // add properties that aren't (or aren't yet) on the package const additions: EpmPackageAdditions = { @@ -123,28 +116,53 @@ export async function getPackageInfo(options: { return createInstallableFrom(updated, savedObject); } +interface PackageResponse { + paths: string[]; + packageInfo: ArchivePackage | RegistryPackage; +} +type GetPackageResponse = PackageResponse | undefined; + // gets package from install_source if it exists otherwise gets from registry export async function getPackageFromSource(options: { pkgName: string; pkgVersion: string; - pkgInstallSource?: InstallSource; -}): Promise<{ - paths: string[] | undefined; - packageInfo: RegistryPackage | ArchivePackage; -}> { - const { pkgName, pkgVersion, pkgInstallSource } = options; - // TODO: Check package storage before checking registry - let res; - if (pkgInstallSource === 'upload') { + installedPkg?: Installation; + savedObjectsClient: SavedObjectsClientContract; +}): Promise { + const { pkgName, pkgVersion, installedPkg, savedObjectsClient } = options; + let res: GetPackageResponse; + // if the package is installed + + if (installedPkg && installedPkg.version === pkgVersion) { + const { install_source: pkgInstallSource } = installedPkg; + // check cache res = getArchivePackage({ name: pkgName, version: pkgVersion, }); + if (!res) { + res = await getEsPackage( + pkgName, + pkgVersion, + installedPkg.package_assets, + savedObjectsClient + ); + } + // for packages not in cache or package storage and installed from registry, check registry + if (!res && pkgInstallSource === 'registry') { + try { + res = await Registry.getRegistryPackage(pkgName, pkgVersion); + // TODO: add to cache and storage here? + } catch (error) { + // treating this is a 404 as no status code returned + // in the unlikely event its missing from cache, storage, and never installed from registry + } + } } else { + // else package is not installed or installed and missing from cache and storage and installed from registry res = await Registry.getRegistryPackage(pkgName, pkgVersion); } - if (!res.packageInfo || !res.paths) - throw new Error(`package info for ${pkgName}-${pkgVersion} does not exist`); + if (!res) throw new Error(`package info for ${pkgName}-${pkgVersion} does not exist`); return { paths: res.paths, packageInfo: res.packageInfo, diff --git a/x-pack/plugins/fleet/server/services/epm/registry/index.ts b/x-pack/plugins/fleet/server/services/epm/registry/index.ts index 90f9afe2350ea..dc4f02c94acde 100644 --- a/x-pack/plugins/fleet/server/services/epm/registry/index.ts +++ b/x-pack/plugins/fleet/server/services/epm/registry/index.ts @@ -163,7 +163,6 @@ export async function getRegistryPackage( } const packageInfo = await getInfo(name, version); - return { paths, packageInfo }; } From 03ef0892364d06768511ba82ad5aad85237f7f95 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Jan 2021 19:36:25 +0200 Subject: [PATCH 03/64] Update dependency vega-tooltip to ^0.25.0 (#87472) * Update dependency vega-tooltip to ^0.25.0 * Update yarn.lock Co-authored-by: Renovate Bot Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Stratoula Kalafateli --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 08ddb36523d8f..8af20d6459373 100644 --- a/package.json +++ b/package.json @@ -832,7 +832,7 @@ "vega": "^5.17.3", "vega-lite": "^4.17.0", "vega-schema-url-parser": "^2.1.0", - "vega-tooltip": "^0.24.2", + "vega-tooltip": "^0.25.0", "venn.js": "0.2.20", "vinyl-fs": "^3.0.3", "wait-on": "^5.0.1", diff --git a/yarn.lock b/yarn.lock index de0951b1dcbdb..e101dff70761c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -28694,10 +28694,10 @@ vega-time@^2.0.3, vega-time@^2.0.4, vega-time@~2.0.4: d3-time "^2.0.0" vega-util "^1.15.2" -vega-tooltip@^0.24.2: - version "0.24.2" - resolved "https://registry.yarnpkg.com/vega-tooltip/-/vega-tooltip-0.24.2.tgz#da55a171a96ea48a8ff135a728622e1cbb1152af" - integrity sha512-b7IeYQl/piNVsMmTliOgTnwSOhBs67KqoZ9UzP1I3XpH7TKbSuc3YHA7b1CSxkRR0hHKdradby4UI8c9rdH74w== +vega-tooltip@^0.25.0: + version "0.25.0" + resolved "https://registry.yarnpkg.com/vega-tooltip/-/vega-tooltip-0.25.0.tgz#c5dcae1b2bd36e1c2e61e69f6ee7a0d0d27a3026" + integrity sha512-S48d/eP6WfieLmUvFEjd+raHWKKeK/RfTlwLa3zGcBULDHJY2NU2vRfjC1x33G6Y7eKeAfqGpM6ER5Qt1nf8tA== dependencies: vega-util "^1.15.2" From f12228e6356d4c9d9ac03ee3cc335e98b526406b Mon Sep 17 00:00:00 2001 From: Justin Ibarra Date: Mon, 11 Jan 2021 08:54:38 -0900 Subject: [PATCH 04/64] [Detection Rules] Add 7.11 rules (#87422) * [Detection Rules] Add 7.11 rules * add empty array for missing technique --- ...tion_added_to_google_workspace_domain.json | 5 +- ...ion_email_powershell_exchange_mailbox.json | 50 ++++++ ...ion_gcp_pub_sub_subscription_creation.json | 7 +- ...collection_gcp_pub_sub_topic_creation.json | 7 +- ...ll_exch_mailbox_activesync_add_device.json | 50 ++++++ ...collection_update_event_hub_auth_rule.json | 7 +- ...json => collection_winrar_encryption.json} | 6 +- ...mand_and_control_cobalt_strike_beacon.json | 15 +- ..._control_dns_directly_to_the_internet.json | 8 +- .../command_and_control_fin7_c2_behavior.json | 19 ++- ...fer_protocol_activity_to_the_internet.json | 8 +- .../command_and_control_halfbaked_beacon.json | 15 +- ...hat_protocol_activity_to_the_internet.json | 8 +- ...d_control_nat_traversal_port_activity.json | 10 +- .../command_and_control_port_26_activity.json | 10 +- ...ol_port_8000_activity_to_the_internet.json | 8 +- ..._to_point_tunneling_protocol_activity.json | 10 +- ...l_proxy_port_activity_to_the_internet.json | 8 +- ...te_desktop_protocol_from_the_internet.json | 8 +- ...d_control_remote_file_copy_powershell.json | 13 +- ...mand_and_control_smtp_to_the_internet.json | 8 +- ..._server_port_activity_to_the_internet.json | 8 +- ...ol_ssh_secure_shell_from_the_internet.json | 8 +- ...trol_ssh_secure_shell_to_the_internet.json | 8 +- ...control_sunburst_c2_activity_detected.json | 76 +++++++++ ...mand_and_control_telnet_port_activity.json | 10 +- ..._control_tor_activity_to_the_internet.json | 5 - ...access_compress_credentials_keychains.json | 15 +- ...cess_domain_backup_dpapi_private_keys.json | 15 +- ...ial_access_iam_user_addition_to_group.json | 10 +- .../credential_access_key_vault_modified.json | 20 ++- ..._365_brute_force_user_account_attempt.json | 3 +- ...65_potential_password_spraying_attack.json | 3 +- ...ccess_storage_account_key_regenerated.json | 7 +- ...den_file_attribute_with_via_attribexe.json | 23 +-- ...evasion_attempt_del_quarantine_attrib.json | 13 +- ...tempt_to_disable_iptables_or_firewall.json | 15 +- ...ion_attempt_to_disable_syslog_service.json | 15 +- ...e_application_credential_modification.json | 59 +++++++ ...on_azure_diagnostic_settings_deletion.json | 20 ++- ...sion_azure_service_principal_addition.json | 60 +++++++ ...se_evasion_cloudtrail_logging_deleted.json | 15 +- ..._evasion_cloudtrail_logging_suspended.json | 15 +- ...nse_evasion_cloudwatch_alarm_deletion.json | 15 +- ..._evasion_config_service_rule_deletion.json | 15 +- ...vasion_configuration_recorder_stopped.json | 15 +- .../defense_evasion_cve_2020_0601.json | 15 +- ...delete_volume_usn_journal_with_fsutil.json | 15 +- ...deleting_backup_catalogs_with_wbadmin.json | 15 +- ...deletion_of_bash_command_line_history.json | 15 +- ...fense_evasion_disable_selinux_attempt.json | 15 +- ...ble_windows_firewall_rules_with_netsh.json | 15 +- ...defense_evasion_ec2_flow_log_deletion.json | 15 +- ...ense_evasion_ec2_network_acl_deletion.json | 15 +- ...evasion_enable_inbound_rdp_with_netsh.json | 13 +- .../defense_evasion_event_hub_deletion.json | 20 ++- ...ecution_msbuild_started_by_office_app.json | 10 +- ...n_execution_msbuild_started_by_script.json | 10 +- ...ion_msbuild_started_by_system_process.json | 10 +- ...cution_msbuild_started_unusal_process.json | 15 +- ...ution_via_trusted_developer_utilities.json | 10 +- ...fense_evasion_file_deletion_via_shred.json | 15 +- ...ense_evasion_firewall_policy_deletion.json | 20 ++- ...nse_evasion_gcp_firewall_rule_created.json | 7 +- ...nse_evasion_gcp_firewall_rule_deleted.json | 7 +- ...se_evasion_gcp_firewall_rule_modified.json | 7 +- ...e_evasion_gcp_logging_bucket_deletion.json | 7 +- ...nse_evasion_gcp_logging_sink_deletion.json | 7 +- ...ion_gcp_pub_sub_subscription_deletion.json | 7 +- ...se_evasion_gcp_pub_sub_topic_deletion.json | 7 +- ...storage_bucket_configuration_modified.json | 7 +- ...p_storage_bucket_permissions_modified.json | 7 +- ...e_evasion_guardduty_detector_deletion.json | 15 +- .../defense_evasion_hidden_file_dir_tmp.json | 23 +-- .../defense_evasion_installutil_beacon.json | 15 +- ...defense_evasion_kernel_module_removal.json | 28 +++- ...osoft_365_exchange_dlp_policy_removed.json | 3 +- ...change_malware_filter_policy_deletion.json | 3 +- ..._365_exchange_malware_filter_rule_mod.json | 3 +- ...65_exchange_safe_attach_rule_disabled.json | 3 +- ...isc_lolbin_connecting_to_the_internet.json | 10 +- ...e_evasion_modification_of_boot_config.json | 15 +- ...n_msbuild_making_network_connections.json} | 8 +- .../defense_evasion_mshta_beacon.json | 15 +- ...son => defense_evasion_msxsl_network.json} | 8 +- ...ense_evasion_network_watcher_deletion.json | 20 ++- ...vasion_port_forwarding_added_registry.json | 13 +- ...defense_evasion_rundll32_no_arguments.json | 13 +- ...ion_scheduledjobs_at_protocol_enabled.json | 13 +- ..._evasion_sdelete_like_filename_rename.json | 13 +- ...ackdoor_service_disabled_via_registry.json | 76 +++++++++ ...vasion_stop_process_service_threshold.json | 13 +- ...efense_evasion_suspicious_scrobj_load.json | 10 +- .../defense_evasion_timestomp_touch.json | 13 +- ...sual_network_connection_via_rundll32.json} | 20 ++- ...n_unusual_process_network_connection.json} | 8 +- ..._volume_shadow_copy_deletion_via_wmic.json | 15 +- .../defense_evasion_waf_acl_deletion.json | 15 +- ...asion_waf_rule_or_rule_group_deletion.json | 15 +- .../discovery_blob_container_access_mod.json | 7 +- ...d_to_google_workspace_trusted_domains.json | 5 +- ...arwinds_backdoor_child_cmd_powershell.json | 73 +++++++++ ...inds_backdoor_unusual_child_processes.json | 73 +++++++++ ...n_command_shell_started_by_powershell.json | 14 +- .../execution_command_shell_via_rundll32.json | 14 +- .../execution_command_virtual_machine.json | 7 +- ...le_program_connecting_to_the_internet.json | 23 +-- .../execution_ms_office_written_file.json | 39 +++-- .../execution_pdf_written_file.json | 39 +++-- ...ution_psexec_lateral_movement_command.json | 23 +-- ...er_program_connecting_to_the_internet.json | 19 +-- ...tion_scheduled_task_powershell_source.json | 51 ++++++ ...json => execution_suspicious_cmd_wmi.json} | 6 +- ...cution_suspicious_powershell_imgload.json} | 19 ++- .../execution_suspicious_psexesvc.json | 13 +- .../execution_via_compiled_html_file.json | 23 +-- .../execution_via_net_com_assemblies.json | 23 +-- ...tration_gcp_logging_sink_modification.json | 7 +- ..._365_exchange_transport_rule_creation.json | 3 +- ...osoft_365_exchange_transport_rule_mod.json | 3 +- .../google_workspace_admin_role_deletion.json | 5 +- ...le_workspace_mfa_enforcement_disabled.json | 5 +- .../google_workspace_policy_modified.json | 5 +- ...pact_azure_automation_runbook_deleted.json | 7 +- .../impact_cloudtrail_logging_updated.json | 15 +- .../impact_cloudwatch_log_group_deletion.json | 15 +- ...impact_cloudwatch_log_stream_deletion.json | 15 +- .../impact_ec2_disable_ebs_encryption.json | 15 +- .../impact_gcp_iam_role_deletion.json | 7 +- .../impact_gcp_service_account_deleted.json | 7 +- .../impact_gcp_service_account_disabled.json | 7 +- .../impact_gcp_storage_bucket_deleted.json | 7 +- ...virtual_private_cloud_network_deleted.json | 7 +- ...p_virtual_private_cloud_route_created.json | 7 +- ...p_virtual_private_cloud_route_deleted.json | 7 +- .../impact_hosts_file_modified.json | 15 +- .../impact_resource_group_deletion.json | 20 ++- ...me_shadow_copy_deletion_via_vssadmin.json} | 8 +- .../rules/prepackaged_rules/index.ts | 150 ++++++++++-------- ...re_active_directory_powershell_signin.json | 60 +++++++ ...tack_via_azure_registered_application.json | 18 ++- ...ial_access_external_guest_user_invite.json | 7 +- ...l_access_gcp_iam_custom_role_creation.json | 7 +- ...5_exchange_anti_phish_policy_deletion.json | 3 +- ...soft_365_exchange_anti_phish_rule_mod.json | 3 +- ...osoft_365_exchange_safelinks_disabled.json | 5 +- ...l_access_script_executing_powershell.json} | 21 ++- ...cess_scripts_process_started_via_wmi.json} | 24 +-- ...s_suspicious_ms_office_child_process.json} | 19 ++- ..._suspicious_ms_outlook_child_process.json} | 21 ++- ..._access_unusual_dns_service_children.json} | 8 +- ...cess_unusual_dns_service_file_writes.json} | 6 +- ...xplorer_suspicious_child_parent_args.json} | 34 ++-- ...=> initial_access_via_system_manager.json} | 24 +-- .../lateral_movement_cmd_service.json | 52 ++++-- ...nt_execution_via_file_shares_sequence.json | 13 +- .../lateral_movement_incoming_wmi.json | 9 ++ ...eral_movement_local_service_commands.json} | 8 +- ...ment_mount_hidden_or_webdav_share_net.json | 13 +- ...ovement_remote_file_copy_hidden_share.json | 13 +- .../lateral_movement_remote_services.json | 6 +- ...l_movement_via_startup_folder_rdp_smb.json | 13 +- ...led_for_google_workspace_organization.json | 5 +- ...exchange_dkim_signing_config_disabled.json | 3 +- ..._teams_custom_app_interaction_allowed.json | 3 +- ...nux_anomalous_kernel_module_arguments.json | 15 +- .../persistence_adobe_hijack_persistence.json | 15 +- .../persistence_app_compat_shim.json | 15 +- .../persistence_appcertdlls_registry.json | 13 +- .../persistence_appinitdlls_registry.json | 13 +- ...ence_azure_automation_account_created.json | 7 +- ...utomation_runbook_created_or_modified.json | 7 +- ...ence_azure_automation_webhook_created.json | 7 +- ...re_conditional_access_policy_modified.json | 7 +- ...nce_azure_pim_user_added_global_admin.json | 7 +- ...ged_identity_management_role_modified.json | 7 +- ...ce_creation_change_launch_agents_file.json | 13 +- .../persistence_ec2_network_acl_creation.json | 8 +- ...tence_evasion_registry_ifeo_injection.json | 13 +- ...gcp_iam_service_account_key_deletion.json} | 13 +- ..._gcp_key_created_for_service_account.json} | 13 +- ...rsistence_gcp_service_account_created.json | 7 +- ...workspace_admin_role_assigned_to_user.json | 5 +- ...a_domain_wide_delegation_of_authority.json | 5 +- ...e_workspace_custom_admin_role_created.json | 5 +- ...stence_google_workspace_role_modified.json | 5 +- ...sistence_gpo_schtask_service_creation.json | 17 +- .../persistence_iam_group_creation.json | 15 +- .../persistence_kernel_module_activity.json | 15 +- ...rsistence_mfa_disabled_for_azure_user.json | 7 +- ...5_exchange_management_role_assignment.json | 3 +- ...oft_365_teams_external_access_enabled.json | 3 +- ...rosoft_365_teams_guest_access_enabled.json | 3 +- ...escalation_via_accessibility_features.json | 26 ++- .../persistence_rds_cluster_creation.json | 16 +- .../persistence_registry_uncommon.json | 9 ++ ...persistence_run_key_and_startup_broad.json | 13 +- ...ce_runtime_run_key_startup_susp_procs.json | 13 +- .../persistence_services_registry.json | 13 +- ...sistence_shell_activity_by_web_server.json | 15 +- ...er_file_written_by_suspicious_process.json | 13 +- ...lder_file_written_by_unsigned_process.json | 13 +- .../persistence_startup_folder_scripts.json | 15 +- ...stence_suspicious_com_hijack_registry.json | 13 +- ...e_suspicious_service_created_registry.json | 13 +- ...ersistence_system_shells_via_services.json | 15 +- ..._added_as_owner_for_azure_application.json | 7 +- ..._as_owner_for_azure_service_principal.json | 7 +- .../persistence_via_application_shimming.json | 28 +++- ...sistence_via_hidden_run_key_valuename.json | 13 +- ...sa_security_support_provider_registry.json | 13 +- ...ia_update_orchestrator_service_hijack.json | 15 +- ...calation_rogue_windir_environment_var.json | 13 +- ...e_escalation_setgid_bit_set_via_chmod.json | 23 +-- ...e_escalation_setuid_bit_set_via_chmod.json | 23 +-- ...privilege_escalation_sudoers_file_mod.json | 15 +- ...lege_escalation_uac_bypass_com_clipup.json | 13 +- ...ge_escalation_uac_bypass_com_ieinstal.json | 13 +- ...n_uac_bypass_com_interface_icmluautil.json | 13 +- ...alation_uac_bypass_diskcleanup_hijack.json | 13 +- ...escalation_uac_bypass_dll_sideloading.json | 13 +- ...ge_escalation_uac_bypass_event_viewer.json | 15 +- ...ege_escalation_uac_bypass_mock_windir.json | 13 +- ...scalation_uac_bypass_winfw_mmc_hijack.json | 13 +- ...tion_unusual_parentchild_relationship.json | 13 +- ...n_unusual_svchost_childproc_childless.json | 13 +- 226 files changed, 2382 insertions(+), 1023 deletions(-) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_email_powershell_exchange_mailbox.json create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_persistence_powershell_exch_mailbox_activesync_add_device.json rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{exfiltration_winrar_encryption.json => collection_winrar_encryption.json} (93%) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_application_credential_modification.json create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_service_principal_addition.json rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{execution_msbuild_making_network_connections.json => defense_evasion_msbuild_making_network_connections.json} (89%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{execution_msxsl_network.json => defense_evasion_msxsl_network.json} (89%) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_solarwinds_backdoor_service_disabled_via_registry.json rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{execution_unusual_network_connection_via_rundll32.json => defense_evasion_unusual_network_connection_via_rundll32.json} (71%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{execution_unusual_process_network_connection.json => defense_evasion_unusual_process_network_connection.json} (94%) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_apt_solarwinds_backdoor_child_cmd_powershell.json create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_apt_solarwinds_backdoor_unusual_child_processes.json create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_scheduled_task_powershell_source.json rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{lateral_movement_suspicious_cmd_wmi.json => execution_suspicious_cmd_wmi.json} (90%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{defense_evasion_suspicious_powershell_imgload.json => execution_suspicious_powershell_imgload.json} (83%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{defense_evasion_volume_shadow_copy_deletion_via_vssadmin.json => impact_volume_shadow_copy_deletion_via_vssadmin.json} (88%) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_powershell_signin.json rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{execution_script_executing_powershell.json => initial_access_script_executing_powershell.json} (66%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{execution_scripts_process_started_via_wmi.json => initial_access_scripts_process_started_via_wmi.json} (82%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{execution_suspicious_ms_office_child_process.json => initial_access_suspicious_ms_office_child_process.json} (81%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{execution_suspicious_ms_outlook_child_process.json => initial_access_suspicious_ms_outlook_child_process.json} (76%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{execution_unusual_dns_service_children.json => initial_access_unusual_dns_service_children.json} (95%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{execution_unusual_dns_service_file_writes.json => initial_access_unusual_dns_service_file_writes.json} (94%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{execution_via_explorer_suspicious_child_parent_args.json => initial_access_via_explorer_suspicious_child_parent_args.json} (62%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{execution_via_system_manager.json => initial_access_via_system_manager.json} (76%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{execution_local_service_commands.json => lateral_movement_local_service_commands.json} (88%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{credential_access_gcp_iam_service_account_key_deletion.json => persistence_gcp_iam_service_account_key_deletion.json} (84%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{credential_access_gcp_key_created_for_service_account.json => persistence_gcp_key_created_for_service_account.json} (84%) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/application_added_to_google_workspace_domain.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/application_added_to_google_workspace_domain.json index b5b2b1994a511..0bb40770b250b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/application_added_to_google_workspace_domain.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/application_added_to_google_workspace_domain.json @@ -8,14 +8,15 @@ ], "from": "now-130m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-google_workspace*" ], "interval": "10m", "language": "kuery", "license": "Elastic License", "name": "Application Added to Google Workspace Domain", "note": "### Important Information Regarding Google Workspace Event Lag Times\n- As per Google's documentation, Google Workspace administrators may observe lag times ranging from minutes up to 3 days between the time of an event's occurrence and the event being visible in the Google Workspace admin/audit logs.\n- This rule is configured to run every 10 minutes with a lookback time of 130 minutes.\n- To reduce the risk of false negatives, consider reducing the interval that the Google Workspace (formerly G Suite) Filebeat module polls Google's reporting API for new events.\n- By default, `var.interval` is set to 2 hours (2h). Consider changing this interval to a lower value, such as 10 minutes (10m).\n- See the following references for further information.\n - https://support.google.com/a/answer/7061566\n - https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-gsuite.html", - "query": "event.dataset:gsuite.admin and event.provider:admin and event.category:iam and event.action:ADD_APPLICATION", + "query": "event.dataset:(gsuite.admin or google_workspace.admin) and event.provider:admin and event.category:iam and event.action:ADD_APPLICATION", "references": [ "https://support.google.com/a/answer/6328701?hl=en#" ], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_email_powershell_exchange_mailbox.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_email_powershell_exchange_mailbox.json new file mode 100644 index 0000000000000..d251cdbfa4ee1 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_email_powershell_exchange_mailbox.json @@ -0,0 +1,50 @@ +{ + "author": [ + "Elastic" + ], + "description": "Identifies the use of the Exchange PowerShell cmdlet, New-MailBoxExportRequest, to export the contents of a primary mailbox or archive to a .pst file. Adversaries may target user email to collect sensitive information.", + "false_positives": [ + "Legitimate exchange system administration activity." + ], + "index": [ + "logs-endpoint.events.*", + "winlogbeat-*" + ], + "language": "eql", + "license": "Elastic License", + "name": "Exporting Exchange Mailbox via PowerShell", + "query": "process where event.type in (\"start\", \"process_started\") and\n process.name: (\"powershell.exe\", \"pwsh.exe\") and process.args : \"New-MailboxExportRequest*\"\n", + "references": [ + "https://www.volexity.com/blog/2020/12/14/dark-halo-leverages-solarwinds-compromise-to-breach-organizations/", + "https://docs.microsoft.com/en-us/powershell/module/exchange/new-mailboxexportrequest?view=exchange-ps" + ], + "risk_score": 47, + "rule_id": "6aace640-e631-4870-ba8e-5fdda09325db", + "severity": "medium", + "tags": [ + "Elastic", + "Host", + "Windows", + "Threat Detection", + "Collection" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0009", + "name": "Collection", + "reference": "https://attack.mitre.org/tactics/TA0009/" + }, + "technique": [ + { + "id": "T1114", + "name": "Email Collection", + "reference": "https://attack.mitre.org/techniques/T1114/" + } + ] + } + ], + "type": "eql", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_gcp_pub_sub_subscription_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_gcp_pub_sub_subscription_creation.json index 6b90ec776926c..a860c189b17af 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_gcp_pub_sub_subscription_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_gcp_pub_sub_subscription_creation.json @@ -7,13 +7,14 @@ "Subscription creations may be done by a system or network administrator. Verify whether the user email, resource name, and/or hostname should be making changes in your environment. Subscription creations from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Pub/Sub Subscription Creation", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:google.pubsub.v*.Subscriber.CreateSubscription and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:google.pubsub.v*.Subscriber.CreateSubscription and event.outcome:success", "references": [ "https://cloud.google.com/pubsub/docs/overview" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_gcp_pub_sub_topic_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_gcp_pub_sub_topic_creation.json index e53c36b236639..0ed94a295705b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_gcp_pub_sub_topic_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_gcp_pub_sub_topic_creation.json @@ -7,13 +7,14 @@ "Topic creations may be done by a system or network administrator. Verify whether the user email, resource name, and/or hostname should be making changes in your environment. Topic creations from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Pub/Sub Topic Creation", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:google.pubsub.v*.Publisher.CreateTopic and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:google.pubsub.v*.Publisher.CreateTopic and event.outcome:success", "references": [ "https://cloud.google.com/pubsub/docs/admin" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_persistence_powershell_exch_mailbox_activesync_add_device.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_persistence_powershell_exch_mailbox_activesync_add_device.json new file mode 100644 index 0000000000000..075d11bcff5ee --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_persistence_powershell_exch_mailbox_activesync_add_device.json @@ -0,0 +1,50 @@ +{ + "author": [ + "Elastic" + ], + "description": "Identifies the use of the Exchange PowerShell cmdlet, Set-CASMailbox, to add a new ActiveSync allowed device. Adversaries may target user email to collect sensitive information.", + "false_positives": [ + "Legitimate exchange system administration activity." + ], + "index": [ + "logs-endpoint.events.*", + "winlogbeat-*" + ], + "language": "eql", + "license": "Elastic License", + "name": "New ActiveSyncAllowedDeviceID Added via PowerShell", + "query": "process where event.type in (\"start\", \"process_started\") and\n process.name: (\"powershell.exe\", \"pwsh.exe\") and process.args : \"Set-CASMailbox*ActiveSyncAllowedDeviceIDs*\"\n", + "references": [ + "https://www.volexity.com/blog/2020/12/14/dark-halo-leverages-solarwinds-compromise-to-breach-organizations/", + "https://docs.microsoft.com/en-us/powershell/module/exchange/set-casmailbox?view=exchange-ps" + ], + "risk_score": 47, + "rule_id": "ce64d965-6cb0-466d-b74f-8d2c76f47f05", + "severity": "medium", + "tags": [ + "Elastic", + "Host", + "Windows", + "Threat Detection", + "Collection" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0009", + "name": "Collection", + "reference": "https://attack.mitre.org/tactics/TA0009/" + }, + "technique": [ + { + "id": "T1114", + "name": "Email Collection", + "reference": "https://attack.mitre.org/techniques/T1114/" + } + ] + } + ], + "type": "eql", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_update_event_hub_auth_rule.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_update_event_hub_auth_rule.json index d65a0bcdbc6d0..3997f659f215b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_update_event_hub_auth_rule.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_update_event_hub_auth_rule.json @@ -8,13 +8,14 @@ ], "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Event Hub Authorization Rule Created or Updated", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.EVENTHUB/NAMESPACES/AUTHORIZATIONRULES/WRITE and event.outcome:Success", + "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.EVENTHUB/NAMESPACES/AUTHORIZATIONRULES/WRITE and event.outcome:(Success or success)", "references": [ "https://docs.microsoft.com/en-us/azure/event-hubs/authorize-access-shared-access-signature" ], @@ -62,5 +63,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_winrar_encryption.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_winrar_encryption.json similarity index 93% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_winrar_encryption.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_winrar_encryption.json index 8be2a1f77f0a7..befb702833e45 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_winrar_encryption.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_winrar_encryption.json @@ -28,9 +28,9 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0010", - "name": "Exfiltration", - "reference": "https://attack.mitre.org/tactics/TA0010/" + "id": "TA0009", + "name": "Collection", + "reference": "https://attack.mitre.org/tactics/TA0009/" }, "technique": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_cobalt_strike_beacon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_cobalt_strike_beacon.json index 27ad410df1fa2..eb8da932659e5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_cobalt_strike_beacon.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_cobalt_strike_beacon.json @@ -42,13 +42,20 @@ "reference": "https://attack.mitre.org/techniques/T1071/" }, { - "id": "T1483", - "name": "Domain Generation Algorithms", - "reference": "https://attack.mitre.org/techniques/T1483/" + "id": "T1568", + "name": "Dynamic Resolution", + "reference": "https://attack.mitre.org/techniques/T1568/", + "subtechnique": [ + { + "id": "T1568.002", + "name": "Domain Generation Algorithms", + "reference": "https://attack.mitre.org/techniques/T1568/002/" + } + ] } ] } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_directly_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_directly_to_the_internet.json index ca9ef1b26f5b1..77184e89a5889 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_directly_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_directly_to_the_internet.json @@ -35,13 +35,7 @@ "name": "Command and Control", "reference": "https://attack.mitre.org/tactics/TA0011/" }, - "technique": [ - { - "id": "T1043", - "name": "Commonly Used Port", - "reference": "https://attack.mitre.org/techniques/T1043/" - } - ] + "technique": [] } ], "type": "query", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_fin7_c2_behavior.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_fin7_c2_behavior.json index 1ea40aad7861a..15d65e0426a9c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_fin7_c2_behavior.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_fin7_c2_behavior.json @@ -35,19 +35,26 @@ "reference": "https://attack.mitre.org/tactics/TA0011/" }, "technique": [ - { - "id": "T1483", - "name": "Domain Generation Algorithms", - "reference": "https://attack.mitre.org/techniques/T1483/" - }, { "id": "T1071", "name": "Application Layer Protocol", "reference": "https://attack.mitre.org/techniques/T1071/" + }, + { + "id": "T1568", + "name": "Dynamic Resolution", + "reference": "https://attack.mitre.org/techniques/T1568/", + "subtechnique": [ + { + "id": "T1568.002", + "name": "Domain Generation Algorithms", + "reference": "https://attack.mitre.org/techniques/T1568/002/" + } + ] } ] } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ftp_file_transfer_protocol_activity_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ftp_file_transfer_protocol_activity_to_the_internet.json index 37b95be7a0c41..4ffc263b6d244 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ftp_file_transfer_protocol_activity_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ftp_file_transfer_protocol_activity_to_the_internet.json @@ -33,13 +33,7 @@ "name": "Command and Control", "reference": "https://attack.mitre.org/tactics/TA0011/" }, - "technique": [ - { - "id": "T1043", - "name": "Commonly Used Port", - "reference": "https://attack.mitre.org/techniques/T1043/" - } - ] + "technique": [] }, { "framework": "MITRE ATT&CK", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_halfbaked_beacon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_halfbaked_beacon.json index 19c2832b4b82e..6eebae68da4a4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_halfbaked_beacon.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_halfbaked_beacon.json @@ -42,13 +42,20 @@ "reference": "https://attack.mitre.org/techniques/T1071/" }, { - "id": "T1483", - "name": "Domain Generation Algorithms", - "reference": "https://attack.mitre.org/techniques/T1483/" + "id": "T1568", + "name": "Dynamic Resolution", + "reference": "https://attack.mitre.org/techniques/T1568/", + "subtechnique": [ + { + "id": "T1568.002", + "name": "Domain Generation Algorithms", + "reference": "https://attack.mitre.org/techniques/T1568/002/" + } + ] } ] } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_irc_internet_relay_chat_protocol_activity_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_irc_internet_relay_chat_protocol_activity_to_the_internet.json index c29ec8c70f78f..510dd45f5b082 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_irc_internet_relay_chat_protocol_activity_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_irc_internet_relay_chat_protocol_activity_to_the_internet.json @@ -33,13 +33,7 @@ "name": "Command and Control", "reference": "https://attack.mitre.org/tactics/TA0011/" }, - "technique": [ - { - "id": "T1043", - "name": "Commonly Used Port", - "reference": "https://attack.mitre.org/techniques/T1043/" - } - ] + "technique": [] }, { "framework": "MITRE ATT&CK", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_nat_traversal_port_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_nat_traversal_port_activity.json index 5afdd1f629ae4..1d552b07b9890 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_nat_traversal_port_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_nat_traversal_port_activity.json @@ -33,15 +33,9 @@ "name": "Command and Control", "reference": "https://attack.mitre.org/tactics/TA0011/" }, - "technique": [ - { - "id": "T1043", - "name": "Commonly Used Port", - "reference": "https://attack.mitre.org/techniques/T1043/" - } - ] + "technique": [] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_26_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_26_activity.json index edd913da4d2b3..36ebb11ac4ec1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_26_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_26_activity.json @@ -37,13 +37,7 @@ "name": "Command and Control", "reference": "https://attack.mitre.org/tactics/TA0011/" }, - "technique": [ - { - "id": "T1043", - "name": "Commonly Used Port", - "reference": "https://attack.mitre.org/techniques/T1043/" - } - ] + "technique": [] }, { "framework": "MITRE ATT&CK", @@ -62,5 +56,5 @@ } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_8000_activity_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_8000_activity_to_the_internet.json index fba51f8c0f3c0..112401d911b9f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_8000_activity_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_8000_activity_to_the_internet.json @@ -33,13 +33,7 @@ "name": "Command and Control", "reference": "https://attack.mitre.org/tactics/TA0011/" }, - "technique": [ - { - "id": "T1043", - "name": "Commonly Used Port", - "reference": "https://attack.mitre.org/techniques/T1043/" - } - ] + "technique": [] } ], "type": "query", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_pptp_point_to_point_tunneling_protocol_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_pptp_point_to_point_tunneling_protocol_activity.json index c706a5b7248c8..b4991f3096a2b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_pptp_point_to_point_tunneling_protocol_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_pptp_point_to_point_tunneling_protocol_activity.json @@ -33,15 +33,9 @@ "name": "Command and Control", "reference": "https://attack.mitre.org/tactics/TA0011/" }, - "technique": [ - { - "id": "T1043", - "name": "Commonly Used Port", - "reference": "https://attack.mitre.org/techniques/T1043/" - } - ] + "technique": [] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_proxy_port_activity_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_proxy_port_activity_to_the_internet.json index 3a7bf829b5364..46a419449b25c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_proxy_port_activity_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_proxy_port_activity_to_the_internet.json @@ -33,13 +33,7 @@ "name": "Command and Control", "reference": "https://attack.mitre.org/tactics/TA0011/" }, - "technique": [ - { - "id": "T1043", - "name": "Commonly Used Port", - "reference": "https://attack.mitre.org/techniques/T1043/" - } - ] + "technique": [] } ], "type": "query", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_rdp_remote_desktop_protocol_from_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_rdp_remote_desktop_protocol_from_the_internet.json index 2e94a13f71795..8c22bc974b240 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_rdp_remote_desktop_protocol_from_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_rdp_remote_desktop_protocol_from_the_internet.json @@ -33,13 +33,7 @@ "name": "Command and Control", "reference": "https://attack.mitre.org/tactics/TA0011/" }, - "technique": [ - { - "id": "T1043", - "name": "Commonly Used Port", - "reference": "https://attack.mitre.org/techniques/T1043/" - } - ] + "technique": [] }, { "framework": "MITRE ATT&CK", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_powershell.json index cb9d215acfda3..5e0a6f8e3e25e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_powershell.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_powershell.json @@ -47,9 +47,16 @@ }, "technique": [ { - "id": "T1086", - "name": "PowerShell", - "reference": "https://attack.mitre.org/techniques/T1086/" + "id": "T1059", + "name": "Command and Scripting Interpreter", + "reference": "https://attack.mitre.org/techniques/T1059/", + "subtechnique": [ + { + "id": "T1059.001", + "name": "PowerShell", + "reference": "https://attack.mitre.org/techniques/T1059/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_smtp_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_smtp_to_the_internet.json index 21c4d22e2af8c..86c2a32d30306 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_smtp_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_smtp_to_the_internet.json @@ -33,13 +33,7 @@ "name": "Command and Control", "reference": "https://attack.mitre.org/tactics/TA0011/" }, - "technique": [ - { - "id": "T1043", - "name": "Commonly Used Port", - "reference": "https://attack.mitre.org/techniques/T1043/" - } - ] + "technique": [] }, { "framework": "MITRE ATT&CK", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sql_server_port_activity_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sql_server_port_activity_to_the_internet.json index 45cfc2bc5fc3b..3c03c162c8c46 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sql_server_port_activity_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sql_server_port_activity_to_the_internet.json @@ -33,13 +33,7 @@ "name": "Command and Control", "reference": "https://attack.mitre.org/tactics/TA0011/" }, - "technique": [ - { - "id": "T1043", - "name": "Commonly Used Port", - "reference": "https://attack.mitre.org/techniques/T1043/" - } - ] + "technique": [] } ], "type": "query", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_from_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_from_the_internet.json index 95e564ff7af2c..bf91c1fda6433 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_from_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_from_the_internet.json @@ -33,13 +33,7 @@ "name": "Command and Control", "reference": "https://attack.mitre.org/tactics/TA0011/" }, - "technique": [ - { - "id": "T1043", - "name": "Commonly Used Port", - "reference": "https://attack.mitre.org/techniques/T1043/" - } - ] + "technique": [] }, { "framework": "MITRE ATT&CK", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_to_the_internet.json index d5e0a29dd2a01..72d669ca9966a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_to_the_internet.json @@ -33,13 +33,7 @@ "name": "Command and Control", "reference": "https://attack.mitre.org/tactics/TA0011/" }, - "technique": [ - { - "id": "T1043", - "name": "Commonly Used Port", - "reference": "https://attack.mitre.org/techniques/T1043/" - } - ] + "technique": [] } ], "type": "query", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json new file mode 100644 index 0000000000000..1138cdbbf5427 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json @@ -0,0 +1,76 @@ +{ + "author": [ + "Elastic" + ], + "description": "The malware known as SUNBURST targets the SolarWind's Orion business software for command and control. This rule detects post-exploitation command and control activity of the SUNBURST backdoor.", + "from": "now-9m", + "index": [ + "logs-endpoint.events.*" + ], + "language": "kuery", + "license": "Elastic License", + "name": "SUNBURST Command and Control Activity", + "note": "The SUNBURST malware attempts to hide within the Orion Improvement Program (OIP) network traffic. As this rule detects post-exploitation network traffic, investigations into this should be prioritized.", + "query": "event.category:network and event.type:protocol and network.protocol:http and process.name:( ConfigurationWizard.exe or NetFlowService.exe or NetflowDatabaseMaintenance.exe or SolarWinds.Administration.exe or SolarWinds.BusinessLayerHost.exe or SolarWinds.BusinessLayerHostx64.exe or SolarWinds.Collector.Service.exe or SolarwindsDiagnostics.exe) and http.request.body.content:(( (*/swip/Upload.ashx* and (POST* or PUT*)) or (*/swip/SystemDescription* and (GET* or HEAD*)) or (*/swip/Events* and (GET* or HEAD*))) and not *solarwinds.com*)", + "references": [ + "https://www.fireeye.com/blog/threat-research/2020/12/evasive-attacker-leverages-solarwinds-supply-chain-compromises-with-sunburst-backdoor.html" + ], + "risk_score": 73, + "rule_id": "22599847-5d13-48cb-8872-5796fee8692b", + "severity": "high", + "tags": [ + "Elastic", + "Host", + "Windows", + "Threat Detection", + "Command and Control" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0011", + "name": "Command and Control", + "reference": "https://attack.mitre.org/tactics/TA0011/" + }, + "technique": [ + { + "id": "T1071", + "name": "Application Layer Protocol", + "reference": "https://attack.mitre.org/techniques/T1071/", + "subtechnique": [ + { + "id": "T1071.001", + "name": "Web Protocols", + "reference": "https://attack.mitre.org/techniques/T1071/001/" + } + ] + } + ] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" + }, + "technique": [ + { + "id": "T1195", + "name": "Supply Chain Compromise", + "reference": "https://attack.mitre.org/techniques/T1195/", + "subtechnique": [ + { + "id": "T1195.002", + "name": "Compromise Software Supply Chain", + "reference": "https://attack.mitre.org/techniques/T1195/002/" + } + ] + } + ] + } + ], + "type": "query", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_telnet_port_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_telnet_port_activity.json index 9007db322ae58..4e740b444c798 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_telnet_port_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_telnet_port_activity.json @@ -33,13 +33,7 @@ "name": "Command and Control", "reference": "https://attack.mitre.org/tactics/TA0011/" }, - "technique": [ - { - "id": "T1043", - "name": "Commonly Used Port", - "reference": "https://attack.mitre.org/techniques/T1043/" - } - ] + "technique": [] }, { "framework": "MITRE ATT&CK", @@ -73,5 +67,5 @@ } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_tor_activity_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_tor_activity_to_the_internet.json index 014c46a09e448..da47076325c11 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_tor_activity_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_tor_activity_to_the_internet.json @@ -34,11 +34,6 @@ "reference": "https://attack.mitre.org/tactics/TA0011/" }, "technique": [ - { - "id": "T1043", - "name": "Commonly Used Port", - "reference": "https://attack.mitre.org/techniques/T1043/" - }, { "id": "T1090", "name": "Proxy", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_compress_credentials_keychains.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_compress_credentials_keychains.json index c13ac69e50987..5783c050abd8b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_compress_credentials_keychains.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_compress_credentials_keychains.json @@ -35,13 +35,20 @@ }, "technique": [ { - "id": "T1142", - "name": "Keychain", - "reference": "https://attack.mitre.org/techniques/T1142/" + "id": "T1555", + "name": "Credentials from Password Stores", + "reference": "https://attack.mitre.org/techniques/T1555/", + "subtechnique": [ + { + "id": "T1555.001", + "name": "Keychain", + "reference": "https://attack.mitre.org/techniques/T1555/001/" + } + ] } ] } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json index eefd6ee9e601b..8ee2a62a36193 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json @@ -37,13 +37,20 @@ }, "technique": [ { - "id": "T1145", - "name": "Private Keys", - "reference": "https://attack.mitre.org/techniques/T1145/" + "id": "T1552", + "name": "Unsecured Credentials", + "reference": "https://attack.mitre.org/techniques/T1552/", + "subtechnique": [ + { + "id": "T1552.004", + "name": "Private Keys", + "reference": "https://attack.mitre.org/techniques/T1552/004/" + } + ] } ] } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iam_user_addition_to_group.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iam_user_addition_to_group.json index 8244cb755787f..6f110adb36569 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iam_user_addition_to_group.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iam_user_addition_to_group.json @@ -39,13 +39,7 @@ "name": "Credential Access", "reference": "https://attack.mitre.org/tactics/TA0006/" }, - "technique": [ - { - "id": "T1098", - "name": "Account Manipulation", - "reference": "https://attack.mitre.org/techniques/T1098/" - } - ] + "technique": [] }, { "framework": "MITRE ATT&CK", @@ -64,5 +58,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_key_vault_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_key_vault_modified.json index 33df4e5930066..74cb19c77a7ca 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_key_vault_modified.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_key_vault_modified.json @@ -8,13 +8,14 @@ ], "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Key Vault Modified", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.KEYVAULT/VAULTS/WRITE and event.outcome:Success", + "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.KEYVAULT/VAULTS/WRITE and event.outcome:(Success or success)", "references": [ "https://docs.microsoft.com/en-us/azure/key-vault/general/basic-concepts", "https://docs.microsoft.com/en-us/azure/key-vault/general/secure-your-key-vault" @@ -40,13 +41,20 @@ }, "technique": [ { - "id": "T1081", - "name": "Credentials in Files", - "reference": "https://attack.mitre.org/techniques/T1081/" + "id": "T1552", + "name": "Unsecured Credentials", + "reference": "https://attack.mitre.org/techniques/T1552/", + "subtechnique": [ + { + "id": "T1552.001", + "name": "Credentials In Files", + "reference": "https://attack.mitre.org/techniques/T1552/001/" + } + ] } ] } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_microsoft_365_brute_force_user_account_attempt.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_microsoft_365_brute_force_user_account_attempt.json index 8bd1d60f6dcaa..7db6d3505413c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_microsoft_365_brute_force_user_account_attempt.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_microsoft_365_brute_force_user_account_attempt.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_microsoft_365_potential_password_spraying_attack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_microsoft_365_potential_password_spraying_attack.json index 348c5506d55f6..5392bacca2527 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_microsoft_365_potential_password_spraying_attack.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_microsoft_365_potential_password_spraying_attack.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_storage_account_key_regenerated.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_storage_account_key_regenerated.json index 62e1aab700680..abb5a2a0f0428 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_storage_account_key_regenerated.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_storage_account_key_regenerated.json @@ -8,13 +8,14 @@ ], "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Storage Account Key Regenerated", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.STORAGE/STORAGEACCOUNTS/REGENERATEKEY/ACTION and event.outcome:Success", + "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.STORAGE/STORAGEACCOUNTS/REGENERATEKEY/ACTION and event.outcome:(Success or success)", "references": [ "https://docs.microsoft.com/en-us/azure/storage/common/storage-account-keys-manage?tabs=azure-portal" ], @@ -47,5 +48,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json index a1ff4bfc890a1..39a1b7d2a9c77 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json @@ -32,9 +32,16 @@ }, "technique": [ { - "id": "T1158", - "name": "Hidden Files and Directories", - "reference": "https://attack.mitre.org/techniques/T1158/" + "id": "T1564", + "name": "Hide Artifacts", + "reference": "https://attack.mitre.org/techniques/T1564/", + "subtechnique": [ + { + "id": "T1564.001", + "name": "Hidden Files and Directories", + "reference": "https://attack.mitre.org/techniques/T1564/001/" + } + ] } ] }, @@ -45,15 +52,9 @@ "name": "Persistence", "reference": "https://attack.mitre.org/tactics/TA0003/" }, - "technique": [ - { - "id": "T1158", - "name": "Hidden Files and Directories", - "reference": "https://attack.mitre.org/techniques/T1158/" - } - ] + "technique": [] } ], "type": "query", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_del_quarantine_attrib.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_del_quarantine_attrib.json index 0c662efe2b310..5792182db4ea0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_del_quarantine_attrib.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_del_quarantine_attrib.json @@ -35,9 +35,16 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_iptables_or_firewall.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_iptables_or_firewall.json index b17e4979a885c..8cc4706324cd1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_iptables_or_firewall.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_iptables_or_firewall.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_syslog_service.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_syslog_service.json index 960000c91e4fa..30dd01b65ddf0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_syslog_service.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_syslog_service.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_application_credential_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_application_credential_modification.json new file mode 100644 index 0000000000000..81568d4b3a947 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_application_credential_modification.json @@ -0,0 +1,59 @@ +{ + "author": [ + "Elastic" + ], + "description": "Identifies when a new credential is added to an application in Azure. An application may use a certificate or secret string to prove its identity when requesting a token. Multiple certificates and secrets can be added for an application and an adversary may abuse this by creating an additional authentication method to evade defenses or persist in an environment.", + "false_positives": [ + "Application credential additions may be done by a system or network administrator. Verify whether the username, hostname, and/or resource name should be making changes in your environment. Application credential additions from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." + ], + "from": "now-25m", + "index": [ + "filebeat-*", + "logs-azure*" + ], + "language": "kuery", + "license": "Elastic License", + "name": "Azure Application Credential Modification", + "note": "The Azure Fleet Integration or Filebeat module must be enabled to use this rule.", + "query": "event.dataset:azure.auditlogs and azure.auditlogs.operation_name:\"Update application - Certificates and secrets management\" and event.outcome:(success or Success)", + "references": [ + "https://msrc-blog.microsoft.com/2020/12/13/customer-guidance-on-recent-nation-state-cyber-attacks/" + ], + "risk_score": 47, + "rule_id": "1a36cace-11a7-43a8-9a10-b497c5a02cd3", + "severity": "medium", + "tags": [ + "Elastic", + "Cloud", + "Azure", + "Continuous Monitoring", + "SecOps", + "Identity and Access" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0005", + "name": "Defense Evasion", + "reference": "https://attack.mitre.org/tactics/TA0005/" + }, + "technique": [ + { + "id": "T1550", + "name": "Use Alternate Authentication Material", + "reference": "https://attack.mitre.org/techniques/T1550/", + "subtechnique": [ + { + "id": "T1550.001", + "name": "Application Access Token", + "reference": "https://attack.mitre.org/techniques/T1550/001/" + } + ] + } + ] + } + ], + "type": "query", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_diagnostic_settings_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_diagnostic_settings_deletion.json index 7721790b5cf97..debf32cbaf58e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_diagnostic_settings_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_diagnostic_settings_deletion.json @@ -8,13 +8,14 @@ ], "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Diagnostic Settings Deletion", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.INSIGHTS/DIAGNOSTICSETTINGS/DELETE and event.outcome:Success", + "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.INSIGHTS/DIAGNOSTICSETTINGS/DELETE and event.outcome:(Success or success)", "references": [ "https://docs.microsoft.com/en-us/azure/azure-monitor/platform/diagnostic-settings" ], @@ -39,13 +40,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_service_principal_addition.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_service_principal_addition.json new file mode 100644 index 0000000000000..60412a7e8ae29 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_service_principal_addition.json @@ -0,0 +1,60 @@ +{ + "author": [ + "Elastic" + ], + "description": "Identifies when a new service principal is added in Azure. An application, hosted service, or automated tool that accesses or modifies resources needs an identity created. This identity is known as a service principal. For security reasons, it's always recommended to use service principals with automated tools rather than allowing them to log in with a user identity.", + "false_positives": [ + "A service principal may be created by a system or network administrator. Verify whether the username, hostname, and/or resource name should be making changes in your environment. Service principal additions from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." + ], + "from": "now-25m", + "index": [ + "filebeat-*", + "logs-azure*" + ], + "language": "kuery", + "license": "Elastic License", + "name": "Azure Service Principal Addition", + "note": "The Azure Fleet Integration or Filebeat module must be enabled to use this rule.", + "query": "event.dataset:azure.auditlogs and azure.auditlogs.operation_name:\"Add service principal\" and event.outcome:(success or Success)", + "references": [ + "https://msrc-blog.microsoft.com/2020/12/13/customer-guidance-on-recent-nation-state-cyber-attacks/", + "https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal" + ], + "risk_score": 47, + "rule_id": "60b6b72f-0fbc-47e7-9895-9ba7627a8b50", + "severity": "medium", + "tags": [ + "Elastic", + "Cloud", + "Azure", + "Continuous Monitoring", + "SecOps", + "Identity and Access" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0005", + "name": "Defense Evasion", + "reference": "https://attack.mitre.org/tactics/TA0005/" + }, + "technique": [ + { + "id": "T1550", + "name": "Use Alternate Authentication Material", + "reference": "https://attack.mitre.org/techniques/T1550/", + "subtechnique": [ + { + "id": "T1550.001", + "name": "Application Access Token", + "reference": "https://attack.mitre.org/techniques/T1550/001/" + } + ] + } + ] + } + ], + "type": "query", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json index 169f429a6dd26..b5983f4245732 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json @@ -42,13 +42,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json index cbd040a7f7a30..ad6ca29a95fc0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json @@ -42,13 +42,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json index e18deb65c497b..52f101caf2164 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json @@ -42,13 +42,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_config_service_rule_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_config_service_rule_deletion.json index b7d9321814fd7..30556a232b0f9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_config_service_rule_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_config_service_rule_deletion.json @@ -42,13 +42,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_configuration_recorder_stopped.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_configuration_recorder_stopped.json index b28572deaf204..abafbed29d9db 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_configuration_recorder_stopped.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_configuration_recorder_stopped.json @@ -42,13 +42,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cve_2020_0601.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cve_2020_0601.json index 3beb71763f1ae..3200579e634f4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cve_2020_0601.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cve_2020_0601.json @@ -30,13 +30,20 @@ }, "technique": [ { - "id": "T1116", - "name": "Code Signing", - "reference": "https://attack.mitre.org/techniques/T1116/" + "id": "T1553", + "name": "Subvert Trust Controls", + "reference": "https://attack.mitre.org/techniques/T1553/", + "subtechnique": [ + { + "id": "T1553.002", + "name": "Code Signing", + "reference": "https://attack.mitre.org/techniques/T1553/002/" + } + ] } ] } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json index 5fde3c462eded..84d46d135527d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1107", - "name": "File Deletion", - "reference": "https://attack.mitre.org/techniques/T1107/" + "id": "T1070", + "name": "Indicator Removal on Host", + "reference": "https://attack.mitre.org/techniques/T1070/", + "subtechnique": [ + { + "id": "T1070.004", + "name": "File Deletion", + "reference": "https://attack.mitre.org/techniques/T1070/004/" + } + ] } ] } ], "type": "query", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_backup_catalogs_with_wbadmin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_backup_catalogs_with_wbadmin.json index 554ccc6972e5d..d209c8e0d4ffd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_backup_catalogs_with_wbadmin.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_backup_catalogs_with_wbadmin.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1107", - "name": "File Deletion", - "reference": "https://attack.mitre.org/techniques/T1107/" + "id": "T1070", + "name": "Indicator Removal on Host", + "reference": "https://attack.mitre.org/techniques/T1070/", + "subtechnique": [ + { + "id": "T1070.004", + "name": "File Deletion", + "reference": "https://attack.mitre.org/techniques/T1070/004/" + } + ] } ] } ], "type": "query", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deletion_of_bash_command_line_history.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deletion_of_bash_command_line_history.json index eef37499c8eb5..79df27b6d4cf5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deletion_of_bash_command_line_history.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deletion_of_bash_command_line_history.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1146", - "name": "Clear Command History", - "reference": "https://attack.mitre.org/techniques/T1146/" + "id": "T1070", + "name": "Indicator Removal on Host", + "reference": "https://attack.mitre.org/techniques/T1070/", + "subtechnique": [ + { + "id": "T1070.003", + "name": "Clear Command History", + "reference": "https://attack.mitre.org/techniques/T1070/003/" + } + ] } ] } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_selinux_attempt.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_selinux_attempt.json index 35476a76fd4b5..4bec79808f644 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_selinux_attempt.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_selinux_attempt.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json index a69fde9f6a5cc..3bd3f09f2267e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json index d36294684698e..1cddd3c971bf7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json @@ -42,13 +42,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_network_acl_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_network_acl_deletion.json index b6ac9be800807..2d36151725faa 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_network_acl_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_network_acl_deletion.json @@ -44,13 +44,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json index 1785d826ce89c..a236e6ecbe6f5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json @@ -32,9 +32,16 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_event_hub_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_event_hub_deletion.json index d09edf473c939..2dc52570aa02b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_event_hub_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_event_hub_deletion.json @@ -8,13 +8,14 @@ ], "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Event Hub Deletion", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.EVENTHUB/NAMESPACES/EVENTHUBS/DELETE and event.outcome:Success", + "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.EVENTHUB/NAMESPACES/EVENTHUBS/DELETE and event.outcome:(Success or success)", "references": [ "https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-about", "https://azure.microsoft.com/en-in/services/event-hubs/", @@ -41,13 +42,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json index c41b3aad2f42c..0ce19860dc09b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json @@ -51,15 +51,9 @@ "name": "Execution", "reference": "https://attack.mitre.org/tactics/TA0002/" }, - "technique": [ - { - "id": "T1127", - "name": "Trusted Developer Utilities Proxy Execution", - "reference": "https://attack.mitre.org/techniques/T1127/" - } - ] + "technique": [] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json index a8e16d8bda238..5f8efa3248e3c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json @@ -48,15 +48,9 @@ "name": "Execution", "reference": "https://attack.mitre.org/tactics/TA0002/" }, - "technique": [ - { - "id": "T1127", - "name": "Trusted Developer Utilities Proxy Execution", - "reference": "https://attack.mitre.org/techniques/T1127/" - } - ] + "technique": [] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json index 60c9a317bbb6c..3ce8ae399d2b7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json @@ -48,15 +48,9 @@ "name": "Execution", "reference": "https://attack.mitre.org/tactics/TA0002/" }, - "technique": [ - { - "id": "T1127", - "name": "Trusted Developer Utilities Proxy Execution", - "reference": "https://attack.mitre.org/techniques/T1127/" - } - ] + "technique": [] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json index 09247d2f21323..dc7a7dfe5a0fd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json @@ -38,13 +38,20 @@ }, "technique": [ { - "id": "T1500", - "name": "Compile After Delivery", - "reference": "https://attack.mitre.org/techniques/T1500/" + "id": "T1027", + "name": "Obfuscated Files or Information", + "reference": "https://attack.mitre.org/techniques/T1027/", + "subtechnique": [ + { + "id": "T1027.004", + "name": "Compile After Delivery", + "reference": "https://attack.mitre.org/techniques/T1027/004/" + } + ] } ] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_via_trusted_developer_utilities.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_via_trusted_developer_utilities.json index 7963c03699f78..c13bb4378826e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_via_trusted_developer_utilities.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_via_trusted_developer_utilities.json @@ -47,15 +47,9 @@ "name": "Execution", "reference": "https://attack.mitre.org/tactics/TA0002/" }, - "technique": [ - { - "id": "T1127", - "name": "Trusted Developer Utilities Proxy Execution", - "reference": "https://attack.mitre.org/techniques/T1127/" - } - ] + "technique": [] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_deletion_via_shred.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_deletion_via_shred.json index dc73b7bc1eb76..cd20a0262f9a9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_deletion_via_shred.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_deletion_via_shred.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1107", - "name": "File Deletion", - "reference": "https://attack.mitre.org/techniques/T1107/" + "id": "T1070", + "name": "Indicator Removal on Host", + "reference": "https://attack.mitre.org/techniques/T1070/", + "subtechnique": [ + { + "id": "T1070.004", + "name": "File Deletion", + "reference": "https://attack.mitre.org/techniques/T1070/004/" + } + ] } ] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_firewall_policy_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_firewall_policy_deletion.json index 69a123ba678fd..6e6accb27213b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_firewall_policy_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_firewall_policy_deletion.json @@ -8,13 +8,14 @@ ], "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Firewall Policy Deletion", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.NETWORK/FIREWALLPOLICIES/DELETE and event.outcome:Success", + "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.NETWORK/FIREWALLPOLICIES/DELETE and event.outcome:(Success or success)", "references": [ "https://docs.microsoft.com/en-us/azure/firewall-manager/policy-overview" ], @@ -39,13 +40,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_created.json index dc08dace20bfc..b29b36a0220cc 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_created.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_created.json @@ -7,13 +7,14 @@ "Firewall rules may be created by system administrators. Verify that the firewall configuration change was expected. Exceptions can be added to this rule to filter expected behavior." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Firewall Rule Creation", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:v*.compute.firewalls.insert", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:v*.compute.firewalls.insert", "references": [ "https://cloud.google.com/vpc/docs/firewalls" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_deleted.json index 7ee5af109f37b..b99c066c55675 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_deleted.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_deleted.json @@ -7,13 +7,14 @@ "Firewall rules may be deleted by system administrators. Verify that the firewall configuration change was expected. Exceptions can be added to this rule to filter expected behavior." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Firewall Rule Deletion", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:v*.compute.firewalls.delete", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:v*.compute.firewalls.delete", "references": [ "https://cloud.google.com/vpc/docs/firewalls" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_modified.json index b4107fb9f08fd..4ad45700a3dca 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_modified.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_modified.json @@ -7,13 +7,14 @@ "Firewall rules may be modified by system administrators. Verify that the firewall configuration change was expected. Exceptions can be added to this rule to filter expected behavior." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Firewall Rule Modification", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:v*.compute.firewalls.patch", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:v*.compute.firewalls.patch", "references": [ "https://cloud.google.com/vpc/docs/firewalls" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_logging_bucket_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_logging_bucket_deletion.json index 079a87b5c615b..976f2a0e28faa 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_logging_bucket_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_logging_bucket_deletion.json @@ -7,13 +7,14 @@ "Logging bucket deletions may be done by a system or network administrator. Verify whether the user email, resource name, and/or hostname should be making changes in your environment. Logging bucket deletions from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Logging Bucket Deletion", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:google.logging.v*.ConfigServiceV*.DeleteBucket and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:google.logging.v*.ConfigServiceV*.DeleteBucket and event.outcome:success", "references": [ "https://cloud.google.com/logging/docs/buckets", "https://cloud.google.com/logging/docs/storage" @@ -47,5 +48,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_logging_sink_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_logging_sink_deletion.json index 8466b618fab98..3690b624f1ed5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_logging_sink_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_logging_sink_deletion.json @@ -7,13 +7,14 @@ "Logging sink deletions may be done by a system or network administrator. Verify whether the user email, resource name, and/or hostname should be making changes in your environment. Logging sink deletions from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Logging Sink Deletion", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:google.logging.v*.ConfigServiceV*.DeleteSink and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:google.logging.v*.ConfigServiceV*.DeleteSink and event.outcome:success", "references": [ "https://cloud.google.com/logging/docs/export" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_pub_sub_subscription_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_pub_sub_subscription_deletion.json index 5b87b8722595c..5fa541484eb57 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_pub_sub_subscription_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_pub_sub_subscription_deletion.json @@ -7,13 +7,14 @@ "Subscription deletions may be done by a system or network administrator. Verify whether the user email, resource name, and/or hostname should be making changes in your environment. Subscription deletions from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Pub/Sub Subscription Deletion", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:google.pubsub.v*.Subscriber.DeleteSubscription and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:google.pubsub.v*.Subscriber.DeleteSubscription and event.outcome:success", "references": [ "https://cloud.google.com/pubsub/docs/overview" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_pub_sub_topic_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_pub_sub_topic_deletion.json index 5a681a35006a7..9f91c70de5519 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_pub_sub_topic_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_pub_sub_topic_deletion.json @@ -7,13 +7,14 @@ "Topic deletions may be done by a system or network administrator. Verify whether the user email, resource name, and/or hostname should be making changes in your environment. Topic deletions from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Pub/Sub Topic Deletion", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:google.pubsub.v*.Publisher.DeleteTopic and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:google.pubsub.v*.Publisher.DeleteTopic and event.outcome:success", "references": [ "https://cloud.google.com/pubsub/docs/overview" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_configuration_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_configuration_modified.json index 5992beef9873e..eaf9dad8011ec 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_configuration_modified.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_configuration_modified.json @@ -7,13 +7,14 @@ "Storage bucket configuration may be modified by system administrators. Verify that the configuration change was expected. Exceptions can be added to this rule to filter expected behavior." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Storage Bucket Configuration Modification", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:storage.buckets.update and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:storage.buckets.update and event.outcome:success", "references": [ "https://cloud.google.com/storage/docs/key-terms#buckets" ], @@ -29,5 +30,5 @@ "Identity and Access" ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_permissions_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_permissions_modified.json index 0687bb1e5178a..dcaa08164676e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_permissions_modified.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_permissions_modified.json @@ -7,13 +7,14 @@ "Storage bucket permissions may be modified by system administrators. Verify that the configuration change was expected. Exceptions can be added to this rule to filter expected behavior." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Storage Bucket Permissions Modification", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:storage.setIamPermissions and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:storage.setIamPermissions and event.outcome:success", "references": [ "https://cloud.google.com/storage/docs/access-control/iam-permissions" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_guardduty_detector_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_guardduty_detector_deletion.json index 50ee5a902b144..48c6040d738bc 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_guardduty_detector_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_guardduty_detector_deletion.json @@ -42,13 +42,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hidden_file_dir_tmp.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hidden_file_dir_tmp.json index c21c15909d82a..340d6da6c7e69 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hidden_file_dir_tmp.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hidden_file_dir_tmp.json @@ -36,9 +36,16 @@ }, "technique": [ { - "id": "T1158", - "name": "Hidden Files and Directories", - "reference": "https://attack.mitre.org/techniques/T1158/" + "id": "T1564", + "name": "Hide Artifacts", + "reference": "https://attack.mitre.org/techniques/T1564/", + "subtechnique": [ + { + "id": "T1564.001", + "name": "Hidden Files and Directories", + "reference": "https://attack.mitre.org/techniques/T1564/001/" + } + ] } ] }, @@ -49,15 +56,9 @@ "name": "Persistence", "reference": "https://attack.mitre.org/tactics/TA0003/" }, - "technique": [ - { - "id": "T1158", - "name": "Hidden Files and Directories", - "reference": "https://attack.mitre.org/techniques/T1158/" - } - ] + "technique": [] } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_installutil_beacon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_installutil_beacon.json index 5f2cd894fae0f..0dd2e51995c9b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_installutil_beacon.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_installutil_beacon.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1118", - "name": "InstallUtil", - "reference": "https://attack.mitre.org/techniques/T1118/" + "id": "T1218", + "name": "Signed Binary Proxy Execution", + "reference": "https://attack.mitre.org/techniques/T1218/", + "subtechnique": [ + { + "id": "T1218.004", + "name": "InstallUtil", + "reference": "https://attack.mitre.org/techniques/T1218/004/" + } + ] } ] } ], "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_kernel_module_removal.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_kernel_module_removal.json index 5c38974b46525..16b150c68e81d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_kernel_module_removal.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_kernel_module_removal.json @@ -38,9 +38,16 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] }, @@ -53,13 +60,20 @@ }, "technique": [ { - "id": "T1215", - "name": "Kernel Modules and Extensions", - "reference": "https://attack.mitre.org/techniques/T1215/" + "id": "T1547", + "name": "Boot or Logon Autostart Execution", + "reference": "https://attack.mitre.org/techniques/T1547/", + "subtechnique": [ + { + "id": "T1547.006", + "name": "Kernel Modules and Extensions", + "reference": "https://attack.mitre.org/techniques/T1547/006/" + } + ] } ] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_dlp_policy_removed.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_dlp_policy_removed.json index 0166512e7361b..1e41c9d0eb9dc 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_dlp_policy_removed.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_dlp_policy_removed.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_policy_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_policy_deletion.json index 7f087c1db21c8..abc7e42a1df3b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_policy_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_policy_deletion.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_rule_mod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_rule_mod.json index 5475d0ee04d36..9fecc079331d5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_rule_mod.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_rule_mod.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_safe_attach_rule_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_safe_attach_rule_disabled.json index 7b5af375da4fe..fd38099e6a340 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_safe_attach_rule_disabled.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_safe_attach_rule_disabled.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_misc_lolbin_connecting_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_misc_lolbin_connecting_to_the_internet.json index e60f5ccebe2f9..686e9a1d4fa49 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_misc_lolbin_connecting_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_misc_lolbin_connecting_to_the_internet.json @@ -45,15 +45,9 @@ "name": "Execution", "reference": "https://attack.mitre.org/tactics/TA0002/" }, - "technique": [ - { - "id": "T1218", - "name": "Signed Binary Proxy Execution", - "reference": "https://attack.mitre.org/techniques/T1218/" - } - ] + "technique": [] } ], "type": "eql", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modification_of_boot_config.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modification_of_boot_config.json index 84ccc52249622..92ce3e821935d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modification_of_boot_config.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modification_of_boot_config.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1107", - "name": "File Deletion", - "reference": "https://attack.mitre.org/techniques/T1107/" + "id": "T1070", + "name": "Indicator Removal on Host", + "reference": "https://attack.mitre.org/techniques/T1070/", + "subtechnique": [ + { + "id": "T1070.004", + "name": "File Deletion", + "reference": "https://attack.mitre.org/techniques/T1070/004/" + } + ] } ] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_msbuild_making_network_connections.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_msbuild_making_network_connections.json similarity index 89% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_msbuild_making_network_connections.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_msbuild_making_network_connections.json index 758e96b8c71f9..b157c7f16f9ac 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_msbuild_making_network_connections.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_msbuild_making_network_connections.json @@ -26,9 +26,9 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0002", - "name": "Execution", - "reference": "https://attack.mitre.org/tactics/TA0002/" + "id": "TA0005", + "name": "Defense Evasion", + "reference": "https://attack.mitre.org/tactics/TA0005/" }, "technique": [ { @@ -40,5 +40,5 @@ } ], "type": "eql", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_mshta_beacon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_mshta_beacon.json index fd19942a33d48..f3da8be382f46 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_mshta_beacon.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_mshta_beacon.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1170", - "name": "Mshta", - "reference": "https://attack.mitre.org/techniques/T1170/" + "id": "T1218", + "name": "Signed Binary Proxy Execution", + "reference": "https://attack.mitre.org/techniques/T1218/", + "subtechnique": [ + { + "id": "T1218.005", + "name": "Mshta", + "reference": "https://attack.mitre.org/techniques/T1218/005/" + } + ] } ] } ], "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_msxsl_network.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_msxsl_network.json similarity index 89% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_msxsl_network.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_msxsl_network.json index be0a7a7ec0a1b..b20766548cb3e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_msxsl_network.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_msxsl_network.json @@ -26,9 +26,9 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0002", - "name": "Execution", - "reference": "https://attack.mitre.org/tactics/TA0002/" + "id": "TA0005", + "name": "Defense Evasion", + "reference": "https://attack.mitre.org/tactics/TA0005/" }, "technique": [ { @@ -40,5 +40,5 @@ } ], "type": "eql", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_network_watcher_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_network_watcher_deletion.json index 0e6d9172eb2c1..66dd691b36967 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_network_watcher_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_network_watcher_deletion.json @@ -8,13 +8,14 @@ ], "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Network Watcher Deletion", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.NETWORK/NETWORKWATCHERS/DELETE and event.outcome:Success", + "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.NETWORK/NETWORKWATCHERS/DELETE and event.outcome:(Success or success)", "references": [ "https://docs.microsoft.com/en-us/azure/network-watcher/network-watcher-monitoring-overview" ], @@ -39,13 +40,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_port_forwarding_added_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_port_forwarding_added_registry.json index b694298622967..bd5d39e79266c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_port_forwarding_added_registry.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_port_forwarding_added_registry.json @@ -35,9 +35,16 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_rundll32_no_arguments.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_rundll32_no_arguments.json index b518ad072e694..8dbc0e5ef76fe 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_rundll32_no_arguments.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_rundll32_no_arguments.json @@ -32,9 +32,16 @@ }, "technique": [ { - "id": "T1085", - "name": "Rundll32", - "reference": "https://attack.mitre.org/techniques/T1085/" + "id": "T1218", + "name": "Signed Binary Proxy Execution", + "reference": "https://attack.mitre.org/techniques/T1218/", + "subtechnique": [ + { + "id": "T1218.011", + "name": "Rundll32", + "reference": "https://attack.mitre.org/techniques/T1218/011/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_scheduledjobs_at_protocol_enabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_scheduledjobs_at_protocol_enabled.json index 6fa2c70520f68..89934fb65495b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_scheduledjobs_at_protocol_enabled.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_scheduledjobs_at_protocol_enabled.json @@ -35,9 +35,16 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_sdelete_like_filename_rename.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_sdelete_like_filename_rename.json index 47df5a750c829..3825419a37c24 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_sdelete_like_filename_rename.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_sdelete_like_filename_rename.json @@ -33,9 +33,16 @@ }, "technique": [ { - "id": "T1107", - "name": "File Deletion", - "reference": "https://attack.mitre.org/techniques/T1107/" + "id": "T1070", + "name": "Indicator Removal on Host", + "reference": "https://attack.mitre.org/techniques/T1070/", + "subtechnique": [ + { + "id": "T1070.004", + "name": "File Deletion", + "reference": "https://attack.mitre.org/techniques/T1070/004/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_solarwinds_backdoor_service_disabled_via_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_solarwinds_backdoor_service_disabled_via_registry.json new file mode 100644 index 0000000000000..451a3f9cfd2f5 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_solarwinds_backdoor_service_disabled_via_registry.json @@ -0,0 +1,76 @@ +{ + "author": [ + "Elastic" + ], + "description": "Identifies a SolarWinds binary modifying the start type of a service to be disabled. An adversary may abuse this technique to manipulate relevant security services.", + "from": "now-9m", + "index": [ + "winlogbeat-*", + "logs-endpoint.events.*" + ], + "language": "eql", + "license": "Elastic License", + "name": "SolarWinds Process Disabling Services via Registry", + "query": "registry where registry.path : \"HKLM\\\\SYSTEM\\\\*ControlSet*\\\\Services\\\\*\\\\Start\" and registry.data.strings == \"4\" and\n process.name : (\n \"SolarWinds.BusinessLayerHost*.exe\", \n \"ConfigurationWizard*.exe\", \n \"NetflowDatabaseMaintenance*.exe\", \n \"NetFlowService*.exe\", \n \"SolarWinds.Administration*.exe\", \n \"SolarWinds.Collector.Service*.exe\" , \n \"SolarwindsDiagnostics*.exe\")\n", + "references": [ + "https://www.fireeye.com/blog/threat-research/2020/12/evasive-attacker-leverages-solarwinds-supply-chain-compromises-with-sunburst-backdoor.html" + ], + "risk_score": 47, + "rule_id": "b9960fef-82c6-4816-befa-44745030e917", + "severity": "medium", + "tags": [ + "Elastic", + "Host", + "Windows", + "Threat Detection", + "Defense Evasion" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0005", + "name": "Defense Evasion", + "reference": "https://attack.mitre.org/tactics/TA0005/" + }, + "technique": [ + { + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] + } + ] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" + }, + "technique": [ + { + "id": "T1195", + "name": "Supply Chain Compromise", + "reference": "https://attack.mitre.org/techniques/T1195/", + "subtechnique": [ + { + "id": "T1195.002", + "name": "Compromise Software Supply Chain", + "reference": "https://attack.mitre.org/techniques/T1195/002/" + } + ] + } + ] + } + ], + "type": "eql", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_stop_process_service_threshold.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_stop_process_service_threshold.json index b638f05a732af..4ee3172fea7eb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_stop_process_service_threshold.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_stop_process_service_threshold.json @@ -32,9 +32,16 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_scrobj_load.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_scrobj_load.json index 16364f590cd0e..2f0f762031faa 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_scrobj_load.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_scrobj_load.json @@ -30,15 +30,9 @@ "name": "Defense Evasion", "reference": "https://attack.mitre.org/tactics/TA0005/" }, - "technique": [ - { - "id": "T1064", - "name": "Scripting", - "reference": "https://attack.mitre.org/techniques/T1064/" - } - ] + "technique": [] } ], "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_timestomp_touch.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_timestomp_touch.json index d14103889a35e..19a08c709e7e6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_timestomp_touch.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_timestomp_touch.json @@ -34,9 +34,16 @@ }, "technique": [ { - "id": "T1099", - "name": "Timestomp", - "reference": "https://attack.mitre.org/techniques/T1099/" + "id": "T1070", + "name": "Indicator Removal on Host", + "reference": "https://attack.mitre.org/techniques/T1070/", + "subtechnique": [ + { + "id": "T1070.006", + "name": "Timestomp", + "reference": "https://attack.mitre.org/techniques/T1070/006/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_network_connection_via_rundll32.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_network_connection_via_rundll32.json similarity index 71% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_network_connection_via_rundll32.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_network_connection_via_rundll32.json index 573b36ed2decf..8c885aa52be59 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_network_connection_via_rundll32.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_network_connection_via_rundll32.json @@ -13,7 +13,6 @@ "name": "Unusual Network Connection via RunDLL32", "query": "sequence by host.id, process.entity_id with maxspan=1m\n [process where event.type in (\"start\", \"process_started\", \"info\") and process.name : \"rundll32.exe\" and process.args_count == 1]\n [network where process.name : \"rundll32.exe\" and network.protocol != \"dns\" and network.direction == \"outgoing\" and\n not cidrmatch(destination.ip, \"10.0.0.0/8\", \"172.16.0.0/12\", \"192.168.0.0/16\", \"127.0.0.0/8\")]\n", "risk_score": 47, - "rule_id": "52aaab7b-b51c-441a-89ce-4387b3aea886", "severity": "medium", "tags": [ @@ -27,15 +26,22 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0002", - "name": "Execution", - "reference": "https://attack.mitre.org/tactics/TA0002/" + "id": "TA0005", + "name": "Defense Evasion", + "reference": "https://attack.mitre.org/tactics/TA0005/" }, "technique": [ { - "id": "T1085", - "name": "Rundll32", - "reference": "https://attack.mitre.org/techniques/T1085/" + "id": "T1218", + "name": "Signed Binary Proxy Execution", + "reference": "https://attack.mitre.org/techniques/T1218/", + "subtechnique": [ + { + "id": "T1218.011", + "name": "Rundll32", + "reference": "https://attack.mitre.org/techniques/T1218/011/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_process_network_connection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_process_network_connection.json similarity index 94% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_process_network_connection.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_process_network_connection.json index 337cf3145fe39..bd8ac27521a43 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_process_network_connection.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_process_network_connection.json @@ -26,9 +26,9 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0002", - "name": "Execution", - "reference": "https://attack.mitre.org/tactics/TA0002/" + "id": "TA0005", + "name": "Defense Evasion", + "reference": "https://attack.mitre.org/tactics/TA0005/" }, "technique": [ { @@ -40,5 +40,5 @@ } ], "type": "eql", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_wmic.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_wmic.json index 49a68f4bfcf66..d4e468d34ef74 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_wmic.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_wmic.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1107", - "name": "File Deletion", - "reference": "https://attack.mitre.org/techniques/T1107/" + "id": "T1070", + "name": "Indicator Removal on Host", + "reference": "https://attack.mitre.org/techniques/T1070/", + "subtechnique": [ + { + "id": "T1070.004", + "name": "File Deletion", + "reference": "https://attack.mitre.org/techniques/T1070/004/" + } + ] } ] } ], "type": "query", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_acl_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_acl_deletion.json index 86ed9e2f9c042..d7b7ebc57dfec 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_acl_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_acl_deletion.json @@ -42,13 +42,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_rule_or_rule_group_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_rule_or_rule_group_deletion.json index 302e89d416f4b..f6927a7b556b2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_rule_or_rule_group_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_rule_or_rule_group_deletion.json @@ -42,13 +42,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_blob_container_access_mod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_blob_container_access_mod.json index 16db02338de55..eff32ea1cc84d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_blob_container_access_mod.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_blob_container_access_mod.json @@ -8,13 +8,14 @@ ], "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Blob Container Access Level Modification", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.STORAGE/STORAGEACCOUNTS/BLOBSERVICES/CONTAINERS/WRITE and event.outcome:Success", + "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.STORAGE/STORAGEACCOUNTS/BLOBSERVICES/CONTAINERS/WRITE and event.outcome:(Success or success)", "references": [ "https://docs.microsoft.com/en-us/azure/storage/blobs/anonymous-read-access-prevent" ], @@ -62,5 +63,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/domain_added_to_google_workspace_trusted_domains.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/domain_added_to_google_workspace_trusted_domains.json index e3c06cae1c229..626b59aaef814 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/domain_added_to_google_workspace_trusted_domains.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/domain_added_to_google_workspace_trusted_domains.json @@ -8,14 +8,15 @@ ], "from": "now-130m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-google_workspace*" ], "interval": "10m", "language": "kuery", "license": "Elastic License", "name": "Domain Added to Google Workspace Trusted Domains", "note": "### Important Information Regarding Google Workspace Event Lag Times\n- As per Google's documentation, Google Workspace administrators may observe lag times ranging from minutes up to 3 days between the time of an event's occurrence and the event being visible in the Google Workspace admin/audit logs.\n- This rule is configured to run every 10 minutes with a lookback time of 130 minutes.\n- To reduce the risk of false negatives, consider reducing the interval that the Google Workspace (formerly G Suite) Filebeat module polls Google's reporting API for new events.\n- By default, `var.interval` is set to 2 hours (2h). Consider changing this interval to a lower value, such as 10 minutes (10m).\n- See the following references for further information.\n - https://support.google.com/a/answer/7061566\n - https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-gsuite.html", - "query": "event.dataset:gsuite.admin and event.provider:admin and event.category:iam and event.action:ADD_TRUSTED_DOMAINS", + "query": "event.dataset:(gsuite.admin or google_workspace.admin) and event.provider:admin and event.category:iam and event.action:ADD_TRUSTED_DOMAINS", "references": [ "https://support.google.com/a/answer/6160020?hl=en" ], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_apt_solarwinds_backdoor_child_cmd_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_apt_solarwinds_backdoor_child_cmd_powershell.json new file mode 100644 index 0000000000000..db9489881e971 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_apt_solarwinds_backdoor_child_cmd_powershell.json @@ -0,0 +1,73 @@ +{ + "author": [ + "Elastic" + ], + "description": "A suspicious SolarWinds child process (Cmd.exe or Powershell.exe) was detected.", + "false_positives": [ + "Trusted SolarWinds child processes. Verify process details such as network connections and file writes." + ], + "from": "now-9m", + "index": [ + "winlogbeat-*", + "logs-endpoint.events.*" + ], + "language": "eql", + "license": "Elastic License", + "name": "Command Execution via SolarWinds Process", + "query": "process where event.type in (\"start\", \"process_started\") and process.name: (\"cmd.exe\", \"powershell.exe\") and\nprocess.parent.name: (\n \"ConfigurationWizard*.exe\",\n \"NetflowDatabaseMaintenance*.exe\",\n \"NetFlowService*.exe\",\n \"SolarWinds.Administration*.exe\",\n \"SolarWinds.Collector.Service*.exe\",\n \"SolarwindsDiagnostics*.exe\"\n )\n", + "references": [ + "https://www.fireeye.com/blog/threat-research/2020/12/evasive-attacker-leverages-solarwinds-supply-chain-compromises-with-sunburst-backdoor.html", + "https://github.com/fireeye/sunburst_countermeasures/blob/main/rules/SUNBURST/hxioc/SOLARWINDS%20SUSPICIOUS%20FILEWRITES%20(METHODOLOGY).ioc" + ], + "risk_score": 47, + "rule_id": "d72e33fc-6e91-42ff-ac8b-e573268c5a87", + "severity": "medium", + "tags": [ + "Elastic", + "Host", + "Windows", + "Threat Detection", + "Execution" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0002", + "name": "Execution", + "reference": "https://attack.mitre.org/tactics/TA0002/" + }, + "technique": [ + { + "id": "T1059", + "name": "Command and Scripting Interpreter", + "reference": "https://attack.mitre.org/techniques/T1059/" + } + ] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" + }, + "technique": [ + { + "id": "T1195", + "name": "Supply Chain Compromise", + "reference": "https://attack.mitre.org/techniques/T1195/", + "subtechnique": [ + { + "id": "T1195.002", + "name": "Compromise Software Supply Chain", + "reference": "https://attack.mitre.org/techniques/T1195/002/" + } + ] + } + ] + } + ], + "type": "eql", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_apt_solarwinds_backdoor_unusual_child_processes.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_apt_solarwinds_backdoor_unusual_child_processes.json new file mode 100644 index 0000000000000..4612d4755d0bc --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_apt_solarwinds_backdoor_unusual_child_processes.json @@ -0,0 +1,73 @@ +{ + "author": [ + "Elastic" + ], + "description": "A suspicious SolarWinds child process was detected, which may indicate an attempt to execute malicious programs.", + "false_positives": [ + "Trusted SolarWinds child processes, verify process details such as network connections and file writes." + ], + "from": "now-9m", + "index": [ + "winlogbeat-*", + "logs-endpoint.events.*" + ], + "language": "eql", + "license": "Elastic License", + "name": "Suspicious SolarWinds Child Process", + "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name: (\"SolarWinds.BusinessLayerHost.exe\", \"SolarWinds.BusinessLayerHostx64.exe\") and\n not process.name : (\n \"APMServiceControl*.exe\",\n \"ExportToPDFCmd*.Exe\",\n \"SolarWinds.Credentials.Orion.WebApi*.exe\",\n \"SolarWinds.Orion.Topology.Calculator*.exe\",\n \"Database-Maint.exe\",\n \"SolarWinds.Orion.ApiPoller.Service.exe\",\n \"WerFault.exe\",\n \"WerMgr.exe\")\n", + "references": [ + "https://www.fireeye.com/blog/threat-research/2020/12/evasive-attacker-leverages-solarwinds-supply-chain-compromises-with-sunburst-backdoor.html", + "https://github.com/fireeye/sunburst_countermeasures/blob/main/rules/SUNBURST/hxioc/SOLARWINDS%20SUSPICIOUS%20CHILD%20PROCESSES%20(METHODOLOGY).ioc" + ], + "risk_score": 47, + "rule_id": "93b22c0a-06a0-4131-b830-b10d5e166ff4", + "severity": "medium", + "tags": [ + "Elastic", + "Host", + "Windows", + "Threat Detection", + "Execution" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0002", + "name": "Execution", + "reference": "https://attack.mitre.org/tactics/TA0002/" + }, + "technique": [ + { + "id": "T1106", + "name": "Native API", + "reference": "https://attack.mitre.org/techniques/T1106/" + } + ] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" + }, + "technique": [ + { + "id": "T1195", + "name": "Supply Chain Compromise", + "reference": "https://attack.mitre.org/techniques/T1195/", + "subtechnique": [ + { + "id": "T1195.002", + "name": "Compromise Software Supply Chain", + "reference": "https://attack.mitre.org/techniques/T1195/002/" + } + ] + } + ] + } + ], + "type": "eql", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_powershell.json index df561f4c0ee1c..3b1161d13b8a8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_powershell.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_powershell.json @@ -34,12 +34,14 @@ { "id": "T1059", "name": "Command and Scripting Interpreter", - "reference": "https://attack.mitre.org/techniques/T1059/" - }, - { - "id": "T1086", - "name": "PowerShell", - "reference": "https://attack.mitre.org/techniques/T1086/" + "reference": "https://attack.mitre.org/techniques/T1059/", + "subtechnique": [ + { + "id": "T1059.001", + "name": "PowerShell", + "reference": "https://attack.mitre.org/techniques/T1059/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_via_rundll32.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_via_rundll32.json index f4808c7e12670..b678f23dd0fe2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_via_rundll32.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_via_rundll32.json @@ -34,12 +34,14 @@ { "id": "T1059", "name": "Command and Scripting Interpreter", - "reference": "https://attack.mitre.org/techniques/T1059/" - }, - { - "id": "T1086", - "name": "PowerShell", - "reference": "https://attack.mitre.org/techniques/T1086/" + "reference": "https://attack.mitre.org/techniques/T1059/", + "subtechnique": [ + { + "id": "T1059.001", + "name": "PowerShell", + "reference": "https://attack.mitre.org/techniques/T1059/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_virtual_machine.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_virtual_machine.json index 31c4d488c6960..ef3a2978ed3eb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_virtual_machine.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_virtual_machine.json @@ -8,13 +8,14 @@ ], "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Command Execution on Virtual Machine", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.COMPUTE/VIRTUALMACHINES/RUNCOMMAND/ACTION and event.outcome:Success", + "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.COMPUTE/VIRTUALMACHINES/RUNCOMMAND/ACTION and event.outcome:(Success or success)", "references": [ "https://adsecurity.org/?p=4277", "https://posts.specterops.io/attacking-azure-azure-ad-and-introducing-powerzure-ca70b330511a", @@ -49,5 +50,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json index a950b7280bb73..b85e74c854636 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json @@ -30,13 +30,7 @@ "name": "Execution", "reference": "https://attack.mitre.org/tactics/TA0002/" }, - "technique": [ - { - "id": "T1223", - "name": "Compiled HTML File", - "reference": "https://attack.mitre.org/techniques/T1223/" - } - ] + "technique": [] }, { "framework": "MITRE ATT&CK", @@ -47,13 +41,20 @@ }, "technique": [ { - "id": "T1223", - "name": "Compiled HTML File", - "reference": "https://attack.mitre.org/techniques/T1223/" + "id": "T1218", + "name": "Signed Binary Proxy Execution", + "reference": "https://attack.mitre.org/techniques/T1218/", + "subtechnique": [ + { + "id": "T1218.001", + "name": "Compiled HTML File", + "reference": "https://attack.mitre.org/techniques/T1218/001/" + } + ] } ] } ], "type": "eql", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_ms_office_written_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_ms_office_written_file.json index 2db46080a4e75..cf1fbc4ba0ba2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_ms_office_written_file.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_ms_office_written_file.json @@ -30,25 +30,36 @@ "name": "Execution", "reference": "https://attack.mitre.org/tactics/TA0002/" }, + "technique": [] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" + }, "technique": [ { - "id": "T1064", - "name": "Scripting", - "reference": "https://attack.mitre.org/techniques/T1064/" - }, - { - "id": "T1192", - "name": "Spearphishing Link", - "reference": "https://attack.mitre.org/techniques/T1192/" - }, - { - "id": "T1193", - "name": "Spearphishing Attachment", - "reference": "https://attack.mitre.org/techniques/T1193/" + "id": "T1566", + "name": "Phishing", + "reference": "https://attack.mitre.org/techniques/T1566/", + "subtechnique": [ + { + "id": "T1566.001", + "name": "Spearphishing Attachment", + "reference": "https://attack.mitre.org/techniques/T1566/001/" + }, + { + "id": "T1566.002", + "name": "Spearphishing Link", + "reference": "https://attack.mitre.org/techniques/T1566/002/" + } + ] } ] } ], "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_pdf_written_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_pdf_written_file.json index a807052cf7b0d..f0d32cf8882bb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_pdf_written_file.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_pdf_written_file.json @@ -30,25 +30,36 @@ "name": "Execution", "reference": "https://attack.mitre.org/tactics/TA0002/" }, + "technique": [] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" + }, "technique": [ { - "id": "T1064", - "name": "Scripting", - "reference": "https://attack.mitre.org/techniques/T1064/" - }, - { - "id": "T1192", - "name": "Spearphishing Link", - "reference": "https://attack.mitre.org/techniques/T1192/" - }, - { - "id": "T1193", - "name": "Spearphishing Attachment", - "reference": "https://attack.mitre.org/techniques/T1193/" + "id": "T1566", + "name": "Phishing", + "reference": "https://attack.mitre.org/techniques/T1566/", + "subtechnique": [ + { + "id": "T1566.001", + "name": "Spearphishing Attachment", + "reference": "https://attack.mitre.org/techniques/T1566/001/" + }, + { + "id": "T1566.002", + "name": "Spearphishing Link", + "reference": "https://attack.mitre.org/techniques/T1566/002/" + } + ] } ] } ], "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_psexec_lateral_movement_command.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_psexec_lateral_movement_command.json index e587444c86296..00a63dded94c6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_psexec_lateral_movement_command.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_psexec_lateral_movement_command.json @@ -35,9 +35,16 @@ }, "technique": [ { - "id": "T1035", - "name": "Service Execution", - "reference": "https://attack.mitre.org/techniques/T1035/" + "id": "T1569", + "name": "System Services", + "reference": "https://attack.mitre.org/techniques/T1569/", + "subtechnique": [ + { + "id": "T1569.002", + "name": "Service Execution", + "reference": "https://attack.mitre.org/techniques/T1569/002/" + } + ] } ] }, @@ -48,15 +55,9 @@ "name": "Lateral Movement", "reference": "https://attack.mitre.org/tactics/TA0008/" }, - "technique": [ - { - "id": "T1035", - "name": "Service Execution", - "reference": "https://attack.mitre.org/techniques/T1035/" - } - ] + "technique": [] } ], "type": "eql", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json index 579e8b549fd02..4a5defb4f42a4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json @@ -33,13 +33,7 @@ "name": "Execution", "reference": "https://attack.mitre.org/tactics/TA0002/" }, - "technique": [ - { - "id": "T1117", - "name": "Regsvr32", - "reference": "https://attack.mitre.org/techniques/T1117/" - } - ] + "technique": [] }, { "framework": "MITRE ATT&CK", @@ -52,11 +46,18 @@ { "id": "T1218", "name": "Signed Binary Proxy Execution", - "reference": "https://attack.mitre.org/techniques/T1218/" + "reference": "https://attack.mitre.org/techniques/T1218/", + "subtechnique": [ + { + "id": "T1218.010", + "name": "Regsvr32", + "reference": "https://attack.mitre.org/techniques/T1218/010/" + } + ] } ] } ], "type": "eql", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_scheduled_task_powershell_source.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_scheduled_task_powershell_source.json new file mode 100644 index 0000000000000..3c7e0d00be907 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_scheduled_task_powershell_source.json @@ -0,0 +1,51 @@ +{ + "author": [ + "Elastic" + ], + "description": "Identifies the PowerShell process loading the Task Scheduler COM DLL followed by an outbound RPC network connection within a short time period. This may indicate lateral movement or remote discovery via scheduled tasks.", + "false_positives": [ + "Legitimate scheduled tasks may be created during installation of new software." + ], + "from": "now-9m", + "index": [ + "winlogbeat-*", + "logs-endpoint.events.*" + ], + "language": "eql", + "license": "Elastic License", + "name": "Outbound Scheduled Task Activity via PowerShell", + "query": "sequence by host.id, process.entity_id with maxspan = 5s\n [library where file.name: \"taskschd.dll\" and process.name: (\"powershell.exe\", \"pwsh.exe\")]\n [network where process.name : (\"powershell.exe\", \"pwsh.exe\") and destination.port == 135 and not destination.address in (\"127.0.0.1\", \"::1\")]\n", + "references": [ + "https://www.volexity.com/blog/2020/12/14/dark-halo-leverages-solarwinds-compromise-to-breach-organizations/" + ], + "risk_score": 47, + "rule_id": "5cd55388-a19c-47c7-8ec4-f41656c2fded", + "severity": "medium", + "tags": [ + "Elastic", + "Host", + "Windows", + "Threat Detection", + "Discovery", + "Lateral Movement" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0002", + "name": "Execution", + "reference": "https://attack.mitre.org/tactics/TA0002/" + }, + "technique": [ + { + "id": "T1053", + "name": "Scheduled Task/Job", + "reference": "https://attack.mitre.org/techniques/T1053/" + } + ] + } + ], + "type": "eql", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_suspicious_cmd_wmi.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_cmd_wmi.json similarity index 90% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_suspicious_cmd_wmi.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_cmd_wmi.json index f19b940e758f7..f8bed2d70d135 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_suspicious_cmd_wmi.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_cmd_wmi.json @@ -26,9 +26,9 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0008", - "name": "Lateral Movement", - "reference": "https://attack.mitre.org/tactics/TA0008/" + "id": "TA0002", + "name": "Execution", + "reference": "https://attack.mitre.org/tactics/TA0002/" }, "technique": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_powershell_imgload.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_powershell_imgload.json similarity index 83% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_powershell_imgload.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_powershell_imgload.json index 9d0d327bc9a77..1b25e40bda591 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_powershell_imgload.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_powershell_imgload.json @@ -26,15 +26,22 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0005", - "name": "Defense Evasion", - "reference": "https://attack.mitre.org/tactics/TA0005/" + "id": "TA0002", + "name": "Execution", + "reference": "https://attack.mitre.org/tactics/TA0002/" }, "technique": [ { - "id": "T1086", - "name": "PowerShell", - "reference": "https://attack.mitre.org/techniques/T1086/" + "id": "T1059", + "name": "Command and Scripting Interpreter", + "reference": "https://attack.mitre.org/techniques/T1059/", + "subtechnique": [ + { + "id": "T1059.001", + "name": "PowerShell", + "reference": "https://attack.mitre.org/techniques/T1059/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_psexesvc.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_psexesvc.json index 039953a9fccd8..4cc37b42ca698 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_psexesvc.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_psexesvc.json @@ -32,9 +32,16 @@ }, "technique": [ { - "id": "T1035", - "name": "Service Execution", - "reference": "https://attack.mitre.org/techniques/T1035/" + "id": "T1569", + "name": "System Services", + "reference": "https://attack.mitre.org/techniques/T1569/", + "subtechnique": [ + { + "id": "T1569.002", + "name": "Service Execution", + "reference": "https://attack.mitre.org/techniques/T1569/002/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_compiled_html_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_compiled_html_file.json index 276e5c18335f5..1cd09146fd35a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_compiled_html_file.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_compiled_html_file.json @@ -32,13 +32,7 @@ "name": "Execution", "reference": "https://attack.mitre.org/tactics/TA0002/" }, - "technique": [ - { - "id": "T1223", - "name": "Compiled HTML File", - "reference": "https://attack.mitre.org/techniques/T1223/" - } - ] + "technique": [] }, { "framework": "MITRE ATT&CK", @@ -49,13 +43,20 @@ }, "technique": [ { - "id": "T1223", - "name": "Compiled HTML File", - "reference": "https://attack.mitre.org/techniques/T1223/" + "id": "T1218", + "name": "Signed Binary Proxy Execution", + "reference": "https://attack.mitre.org/techniques/T1218/", + "subtechnique": [ + { + "id": "T1218.001", + "name": "Compiled HTML File", + "reference": "https://attack.mitre.org/techniques/T1218/001/" + } + ] } ] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_net_com_assemblies.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_net_com_assemblies.json index 0a21599c31a4a..ec7bdd88bb0c3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_net_com_assemblies.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_net_com_assemblies.json @@ -30,13 +30,7 @@ "name": "Execution", "reference": "https://attack.mitre.org/tactics/TA0002/" }, - "technique": [ - { - "id": "T1121", - "name": "Regsvcs/Regasm", - "reference": "https://attack.mitre.org/techniques/T1121/" - } - ] + "technique": [] }, { "framework": "MITRE ATT&CK", @@ -47,13 +41,20 @@ }, "technique": [ { - "id": "T1121", - "name": "Regsvcs/Regasm", - "reference": "https://attack.mitre.org/techniques/T1121/" + "id": "T1218", + "name": "Signed Binary Proxy Execution", + "reference": "https://attack.mitre.org/techniques/T1218/", + "subtechnique": [ + { + "id": "T1218.009", + "name": "Regsvcs/Regasm", + "reference": "https://attack.mitre.org/techniques/T1218/009/" + } + ] } ] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_gcp_logging_sink_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_gcp_logging_sink_modification.json index 5e3cc2da2f871..4d55bff56d3a1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_gcp_logging_sink_modification.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_gcp_logging_sink_modification.json @@ -7,13 +7,14 @@ "Logging sink modifications may be done by a system or network administrator. Verify whether the user email, resource name, and/or hostname should be making changes in your environment. Sink modifications from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Logging Sink Modification", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:google.logging.v*.ConfigServiceV*.UpdateSink and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:google.logging.v*.ConfigServiceV*.UpdateSink and event.outcome:success", "references": [ "https://cloud.google.com/logging/docs/export#how_sinks_work" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_creation.json index e56773fc9a004..e8a2d4644e41e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_creation.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_mod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_mod.json index 1b8243c67d1a2..fa17b977ddb81 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_mod.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_mod.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/google_workspace_admin_role_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/google_workspace_admin_role_deletion.json index 3703faa62ddf3..9f22ac76ca1ee 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/google_workspace_admin_role_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/google_workspace_admin_role_deletion.json @@ -8,14 +8,15 @@ ], "from": "now-130m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-google_workspace*" ], "interval": "10m", "language": "kuery", "license": "Elastic License", "name": "Google Workspace Admin Role Deletion", "note": "### Important Information Regarding Google Workspace Event Lag Times\n- As per Google's documentation, Google Workspace administrators may observe lag times ranging from minutes up to 3 days between the time of an event's occurrence and the event being visible in the Google Workspace admin/audit logs.\n- This rule is configured to run every 10 minutes with a lookback time of 130 minutes.\n- To reduce the risk of false negatives, consider reducing the interval that the Google Workspace (formerly G Suite) Filebeat module polls Google's reporting API for new events.\n- By default, `var.interval` is set to 2 hours (2h). Consider changing this interval to a lower value, such as 10 minutes (10m).\n- See the following references for further information.\n - https://support.google.com/a/answer/7061566\n - https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-gsuite.html", - "query": "event.dataset:gsuite.admin and event.provider:admin and event.category:iam and event.action:DELETE_ROLE", + "query": "event.dataset:(gsuite.admin or google_workspace.admin) and event.provider:admin and event.category:iam and event.action:DELETE_ROLE", "references": [ "https://support.google.com/a/answer/2406043?hl=en" ], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/google_workspace_mfa_enforcement_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/google_workspace_mfa_enforcement_disabled.json index 9fcf76532bdd9..5cd725afe7a2d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/google_workspace_mfa_enforcement_disabled.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/google_workspace_mfa_enforcement_disabled.json @@ -8,14 +8,15 @@ ], "from": "now-130m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-google_workspace*" ], "interval": "10m", "language": "kuery", "license": "Elastic License", "name": "Google Workspace MFA Enforcement Disabled", "note": "### Important Information Regarding Google Workspace Event Lag Times\n- As per Google's documentation, Google Workspace administrators may observe lag times ranging from minutes up to 3 days between the time of an event's occurrence and the event being visible in the Google Workspace admin/audit logs.\n- This rule is configured to run every 10 minutes with a lookback time of 130 minutes.\n- To reduce the risk of false negatives, consider reducing the interval that the Google Workspace (formerly G Suite) Filebeat module polls Google's reporting API for new events.\n- By default, `var.interval` is set to 2 hours (2h). Consider changing this interval to a lower value, such as 10 minutes (10m).\n- See the following references for further information.\n - https://support.google.com/a/answer/7061566\n - https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-gsuite.html", - "query": "event.dataset:gsuite.admin and event.provider:admin and event.category:iam and event.action:ENFORCE_STRONG_AUTHENTICATION and gsuite.admin.new_value:false", + "query": "event.dataset:(gsuite.admin or google_workspace.admin) and event.provider:admin and event.category:iam and event.action:ENFORCE_STRONG_AUTHENTICATION and gsuite.admin.new_value:false", "references": [ "https://support.google.com/a/answer/9176657?hl=en#" ], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/google_workspace_policy_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/google_workspace_policy_modified.json index 2db5d9260730e..69290f0a579d0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/google_workspace_policy_modified.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/google_workspace_policy_modified.json @@ -8,14 +8,15 @@ ], "from": "now-130m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-google_workspace*" ], "interval": "10m", "language": "kuery", "license": "Elastic License", "name": "Google Workspace Password Policy Modified", "note": "### Important Information Regarding Google Workspace Event Lag Times\n- As per Google's documentation, Google Workspace administrators may observe lag times ranging from minutes up to 3 days between the time of an event's occurrence and the event being visible in the Google Workspace admin/audit logs.\n- This rule is configured to run every 10 minutes with a lookback time of 130 minutes.\n- To reduce the risk of false negatives, consider reducing the interval that the Google Workspace (formerly G Suite) Filebeat module polls Google's reporting API for new events.\n- By default, `var.interval` is set to 2 hours (2h). Consider changing this interval to a lower value, such as 10 minutes (10m).\n- See the following references for further information.\n - https://support.google.com/a/answer/7061566\n - https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-gsuite.html", - "query": "event.dataset:gsuite.admin and event.provider:admin and event.category:iam and event.action:(CHANGE_APPLICATION_SETTING or CREATE_APPLICATION_SETTING) and gsuite.admin.setting.name:( \"Password Management - Enforce strong password\" or \"Password Management - Password reset frequency\" or \"Password Management - Enable password reuse\" or \"Password Management - Enforce password policy at next login\" or \"Password Management - Minimum password length\" or \"Password Management - Maximum password length\" )", + "query": "event.dataset:(gsuite.admin or google_workspace.admin) and event.provider:admin and event.category:iam and event.action:(CHANGE_APPLICATION_SETTING or CREATE_APPLICATION_SETTING) and gsuite.admin.setting.name:( \"Password Management - Enforce strong password\" or \"Password Management - Password reset frequency\" or \"Password Management - Enable password reuse\" or \"Password Management - Enforce password policy at next login\" or \"Password Management - Minimum password length\" or \"Password Management - Maximum password length\" )", "risk_score": 47, "rule_id": "a99f82f5-8e77-4f8b-b3ce-10c0f6afbc73", "severity": "medium", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_azure_automation_runbook_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_azure_automation_runbook_deleted.json index f474357cc6e2c..4c01c045e833f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_azure_automation_runbook_deleted.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_azure_automation_runbook_deleted.json @@ -5,13 +5,14 @@ "description": "Identifies when an Azure Automation runbook is deleted. An adversary may delete an Azure Automation runbook in order to disrupt their target's automated business operations or to remove a malicious runbook that was used for persistence.", "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Automation Runbook Deleted", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.AUTOMATION/AUTOMATIONACCOUNTS/RUNBOOKS/DELETE and event.outcome:Success", + "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.AUTOMATION/AUTOMATIONACCOUNTS/RUNBOOKS/DELETE and event.outcome:(Success or success)", "references": [ "https://powerzure.readthedocs.io/en/latest/Functions/operational.html#create-backdoor", "https://github.com/hausec/PowerZure", @@ -30,5 +31,5 @@ "Configuration Audit" ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudtrail_logging_updated.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudtrail_logging_updated.json index d7f4c2b19bc0f..a075319f08be2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudtrail_logging_updated.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudtrail_logging_updated.json @@ -42,9 +42,16 @@ }, "technique": [ { - "id": "T1492", - "name": "Stored Data Manipulation", - "reference": "https://attack.mitre.org/techniques/T1492/" + "id": "T1565", + "name": "Data Manipulation", + "reference": "https://attack.mitre.org/techniques/T1565/", + "subtechnique": [ + { + "id": "T1565.001", + "name": "Stored Data Manipulation", + "reference": "https://attack.mitre.org/techniques/T1565/001/" + } + ] } ] }, @@ -65,5 +72,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_group_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_group_deletion.json index ae978f6564d67..44719cf93d6d1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_group_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_group_deletion.json @@ -57,13 +57,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json index 7b985fdb6f693..9e7376e855283 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json @@ -57,13 +57,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_ec2_disable_ebs_encryption.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_ec2_disable_ebs_encryption.json index c60619e894717..da2861ca17ddc 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_ec2_disable_ebs_encryption.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_ec2_disable_ebs_encryption.json @@ -43,13 +43,20 @@ }, "technique": [ { - "id": "T1492", - "name": "Stored Data Manipulation", - "reference": "https://attack.mitre.org/techniques/T1492/" + "id": "T1565", + "name": "Data Manipulation", + "reference": "https://attack.mitre.org/techniques/T1565/", + "subtechnique": [ + { + "id": "T1565.001", + "name": "Stored Data Manipulation", + "reference": "https://attack.mitre.org/techniques/T1565/001/" + } + ] } ] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_iam_role_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_iam_role_deletion.json index 09a9996680155..3721cfcd1a763 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_iam_role_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_iam_role_deletion.json @@ -7,13 +7,14 @@ "Role deletions may be done by a system or network administrator. Verify whether the user email, resource name, and/or hostname should be making changes in your environment. Role deletions from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP IAM Role Deletion", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:google.iam.admin.v*.DeleteRole and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:google.iam.admin.v*.DeleteRole and event.outcome:success", "references": [ "https://cloud.google.com/iam/docs/understanding-roles" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_service_account_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_service_account_deleted.json index 9d34f31c1700d..9a6e9722608ab 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_service_account_deleted.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_service_account_deleted.json @@ -7,13 +7,14 @@ "Service accounts may be deleted by system administrators. Verify that the behavior was expected. Exceptions can be added to this rule to filter expected behavior." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Service Account Deletion", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:google.iam.admin.v*.DeleteServiceAccount and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:google.iam.admin.v*.DeleteServiceAccount and event.outcome:success", "references": [ "https://cloud.google.com/iam/docs/service-accounts" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_service_account_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_service_account_disabled.json index 606ebd1e6128e..b8e89f2e8ebc4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_service_account_disabled.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_service_account_disabled.json @@ -7,13 +7,14 @@ "Service accounts may be disabled by system administrators. Verify that the behavior was expected. Exceptions can be added to this rule to filter expected behavior." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Service Account Disabled", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:google.iam.admin.v*.DisableServiceAccount and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:google.iam.admin.v*.DisableServiceAccount and event.outcome:success", "references": [ "https://cloud.google.com/iam/docs/service-accounts" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_storage_bucket_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_storage_bucket_deleted.json index 859c59ff8a325..017d371e7f15e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_storage_bucket_deleted.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_storage_bucket_deleted.json @@ -7,13 +7,14 @@ "Storage buckets may be deleted by a system or network administrator. Verify whether the user email, resource name, and/or hostname should be making changes in your environment. Bucket deletions from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Storage Bucket Deletion", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:storage.buckets.delete", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:storage.buckets.delete", "references": [ "https://cloud.google.com/storage/docs/key-terms#buckets" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_network_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_network_deleted.json index 7f702f11a9515..6fb6a522eec66 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_network_deleted.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_network_deleted.json @@ -7,13 +7,14 @@ "Virtual Private Cloud networks may be deleted by system administrators. Verify that the configuration change was expected. Exceptions can be added to this rule to filter expected behavior." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Virtual Private Cloud Network Deletion", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:v*.compute.networks.delete and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:v*.compute.networks.delete and event.outcome:success", "references": [ "https://cloud.google.com/vpc/docs/vpc" ], @@ -29,5 +30,5 @@ "Configuration Audit" ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_route_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_route_created.json index 1da90189f96b8..1588a03b8ca6c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_route_created.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_route_created.json @@ -7,13 +7,14 @@ "Virtual Private Cloud routes may be created by system administrators. Verify that the configuration change was expected. Exceptions can be added to this rule to filter expected behavior." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Virtual Private Cloud Route Creation", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:(v*.compute.routes.insert or beta.compute.routes.insert)", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:(v*.compute.routes.insert or beta.compute.routes.insert)", "references": [ "https://cloud.google.com/vpc/docs/routes", "https://cloud.google.com/vpc/docs/using-routes" @@ -30,5 +31,5 @@ "Configuration Audit" ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_route_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_route_deleted.json index c379f07f021a6..6ee7194fa4f5b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_route_deleted.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_route_deleted.json @@ -7,13 +7,14 @@ "Virtual Private Cloud routes may be deleted by system administrators. Verify that the configuration change was expected. Exceptions can be added to this rule to filter expected behavior." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Virtual Private Cloud Route Deletion", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:v*.compute.routes.delete and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:v*.compute.routes.delete and event.outcome:success", "references": [ "https://cloud.google.com/vpc/docs/routes", "https://cloud.google.com/vpc/docs/using-routes" @@ -30,5 +31,5 @@ "Configuration Audit" ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_hosts_file_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_hosts_file_modified.json index 5d7e0bec4332c..a220887dad7f3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_hosts_file_modified.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_hosts_file_modified.json @@ -39,13 +39,20 @@ }, "technique": [ { - "id": "T1492", - "name": "Stored Data Manipulation", - "reference": "https://attack.mitre.org/techniques/T1492/" + "id": "T1565", + "name": "Data Manipulation", + "reference": "https://attack.mitre.org/techniques/T1565/", + "subtechnique": [ + { + "id": "T1565.001", + "name": "Stored Data Manipulation", + "reference": "https://attack.mitre.org/techniques/T1565/001/" + } + ] } ] } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_resource_group_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_resource_group_deletion.json index 8086c09e4b174..59c46e94a34ba 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_resource_group_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_resource_group_deletion.json @@ -8,13 +8,14 @@ ], "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Resource Group Deletion", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.RESOURCES/SUBSCRIPTIONS/RESOURCEGROUPS/DELETE and event.outcome:Success", + "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.RESOURCES/SUBSCRIPTIONS/RESOURCEGROUPS/DELETE and event.outcome:(Success or success)", "references": [ "https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/manage-resource-groups-portal" ], @@ -54,13 +55,20 @@ }, "technique": [ { - "id": "T1089", - "name": "Disabling Security Tools", - "reference": "https://attack.mitre.org/techniques/T1089/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_vssadmin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_vssadmin.json similarity index 88% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_vssadmin.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_vssadmin.json index 493ee919000dc..3fffbf8d9d96f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_vssadmin.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_vssadmin.json @@ -26,9 +26,9 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0005", - "name": "Defense Evasion", - "reference": "https://attack.mitre.org/tactics/TA0005/" + "id": "TA0040", + "name": "Impact", + "reference": "https://attack.mitre.org/tactics/TA0040/" }, "technique": [ { @@ -40,5 +40,5 @@ } ], "type": "query", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts index 1fa1bfe57b483..02f141b3af0a8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts @@ -39,46 +39,46 @@ import rule27 from './defense_evasion_disable_windows_firewall_rules_with_netsh. import rule28 from './defense_evasion_encoding_or_decoding_files_via_certutil.json'; import rule29 from './defense_evasion_execution_via_trusted_developer_utilities.json'; import rule30 from './defense_evasion_misc_lolbin_connecting_to_the_internet.json'; -import rule31 from './defense_evasion_via_filter_manager.json'; -import rule32 from './defense_evasion_volume_shadow_copy_deletion_via_vssadmin.json'; -import rule33 from './defense_evasion_volume_shadow_copy_deletion_via_wmic.json'; -import rule34 from './discovery_process_discovery_via_tasklist_command.json'; -import rule35 from './discovery_whoami_command_activity.json'; -import rule36 from './discovery_whoami_commmand.json'; -import rule37 from './endpoint_adversary_behavior_detected.json'; -import rule38 from './endpoint_cred_dumping_detected.json'; -import rule39 from './endpoint_cred_dumping_prevented.json'; -import rule40 from './endpoint_cred_manipulation_detected.json'; -import rule41 from './endpoint_cred_manipulation_prevented.json'; -import rule42 from './endpoint_exploit_detected.json'; -import rule43 from './endpoint_exploit_prevented.json'; -import rule44 from './endpoint_malware_detected.json'; -import rule45 from './endpoint_malware_prevented.json'; -import rule46 from './endpoint_permission_theft_detected.json'; -import rule47 from './endpoint_permission_theft_prevented.json'; -import rule48 from './endpoint_process_injection_detected.json'; -import rule49 from './endpoint_process_injection_prevented.json'; -import rule50 from './endpoint_ransomware_detected.json'; -import rule51 from './endpoint_ransomware_prevented.json'; -import rule52 from './execution_command_prompt_connecting_to_the_internet.json'; -import rule53 from './execution_command_shell_started_by_powershell.json'; -import rule54 from './execution_command_shell_started_by_svchost.json'; -import rule55 from './execution_html_help_executable_program_connecting_to_the_internet.json'; -import rule56 from './execution_local_service_commands.json'; -import rule57 from './execution_msbuild_making_network_connections.json'; +import rule31 from './defense_evasion_msbuild_making_network_connections.json'; +import rule32 from './defense_evasion_unusual_network_connection_via_rundll32.json'; +import rule33 from './defense_evasion_unusual_process_network_connection.json'; +import rule34 from './defense_evasion_via_filter_manager.json'; +import rule35 from './defense_evasion_volume_shadow_copy_deletion_via_wmic.json'; +import rule36 from './discovery_process_discovery_via_tasklist_command.json'; +import rule37 from './discovery_whoami_command_activity.json'; +import rule38 from './discovery_whoami_commmand.json'; +import rule39 from './endpoint_adversary_behavior_detected.json'; +import rule40 from './endpoint_cred_dumping_detected.json'; +import rule41 from './endpoint_cred_dumping_prevented.json'; +import rule42 from './endpoint_cred_manipulation_detected.json'; +import rule43 from './endpoint_cred_manipulation_prevented.json'; +import rule44 from './endpoint_exploit_detected.json'; +import rule45 from './endpoint_exploit_prevented.json'; +import rule46 from './endpoint_malware_detected.json'; +import rule47 from './endpoint_malware_prevented.json'; +import rule48 from './endpoint_permission_theft_detected.json'; +import rule49 from './endpoint_permission_theft_prevented.json'; +import rule50 from './endpoint_process_injection_detected.json'; +import rule51 from './endpoint_process_injection_prevented.json'; +import rule52 from './endpoint_ransomware_detected.json'; +import rule53 from './endpoint_ransomware_prevented.json'; +import rule54 from './execution_command_prompt_connecting_to_the_internet.json'; +import rule55 from './execution_command_shell_started_by_powershell.json'; +import rule56 from './execution_command_shell_started_by_svchost.json'; +import rule57 from './execution_html_help_executable_program_connecting_to_the_internet.json'; import rule58 from './execution_psexec_lateral_movement_command.json'; import rule59 from './execution_register_server_program_connecting_to_the_internet.json'; -import rule60 from './execution_script_executing_powershell.json'; -import rule61 from './execution_suspicious_ms_office_child_process.json'; -import rule62 from './execution_suspicious_ms_outlook_child_process.json'; -import rule63 from './execution_unusual_network_connection_via_rundll32.json'; -import rule64 from './execution_unusual_process_network_connection.json'; -import rule65 from './execution_via_compiled_html_file.json'; -import rule66 from './initial_access_rdp_remote_desktop_protocol_to_the_internet.json'; -import rule67 from './initial_access_rpc_remote_procedure_call_from_the_internet.json'; -import rule68 from './initial_access_rpc_remote_procedure_call_to_the_internet.json'; -import rule69 from './initial_access_smb_windows_file_sharing_activity_to_the_internet.json'; -import rule70 from './lateral_movement_direct_outbound_smb_connection.json'; +import rule60 from './execution_via_compiled_html_file.json'; +import rule61 from './impact_volume_shadow_copy_deletion_via_vssadmin.json'; +import rule62 from './initial_access_rdp_remote_desktop_protocol_to_the_internet.json'; +import rule63 from './initial_access_rpc_remote_procedure_call_from_the_internet.json'; +import rule64 from './initial_access_rpc_remote_procedure_call_to_the_internet.json'; +import rule65 from './initial_access_script_executing_powershell.json'; +import rule66 from './initial_access_smb_windows_file_sharing_activity_to_the_internet.json'; +import rule67 from './initial_access_suspicious_ms_office_child_process.json'; +import rule68 from './initial_access_suspicious_ms_outlook_child_process.json'; +import rule69 from './lateral_movement_direct_outbound_smb_connection.json'; +import rule70 from './lateral_movement_local_service_commands.json'; import rule71 from './linux_hping_activity.json'; import rule72 from './linux_iodine_activity.json'; import rule73 from './linux_mknod_activity.json'; @@ -99,8 +99,8 @@ import rule87 from './persistence_via_application_shimming.json'; import rule88 from './privilege_escalation_unusual_parentchild_relationship.json'; import rule89 from './defense_evasion_modification_of_boot_config.json'; import rule90 from './privilege_escalation_uac_bypass_event_viewer.json'; -import rule91 from './discovery_net_command_system_account.json'; -import rule92 from './execution_msxsl_network.json'; +import rule91 from './defense_evasion_msxsl_network.json'; +import rule92 from './discovery_net_command_system_account.json'; import rule93 from './command_and_control_certutil_network_connection.json'; import rule94 from './defense_evasion_cve_2020_0601.json'; import rule95 from './credential_access_credential_dumping_msbuild.json'; @@ -204,7 +204,7 @@ import rule192 from './command_and_control_cobalt_strike_beacon.json'; import rule193 from './command_and_control_fin7_c2_behavior.json'; import rule194 from './command_and_control_halfbaked_beacon.json'; import rule195 from './credential_access_secretsmanager_getsecretvalue.json'; -import rule196 from './execution_via_system_manager.json'; +import rule196 from './initial_access_via_system_manager.json'; import rule197 from './privilege_escalation_root_login_without_mfa.json'; import rule198 from './privilege_escalation_updateassumerolepolicy.json'; import rule199 from './impact_hosts_file_modified.json'; @@ -217,8 +217,8 @@ import rule205 from './ml_cloudtrail_rare_method_by_country.json'; import rule206 from './ml_cloudtrail_rare_method_by_user.json'; import rule207 from './credential_access_aws_iam_assume_role_brute_force.json'; import rule208 from './credential_access_okta_brute_force_or_password_spraying.json'; -import rule209 from './execution_unusual_dns_service_children.json'; -import rule210 from './execution_unusual_dns_service_file_writes.json'; +import rule209 from './initial_access_unusual_dns_service_children.json'; +import rule210 from './initial_access_unusual_dns_service_file_writes.json'; import rule211 from './lateral_movement_dns_server_overflow.json'; import rule212 from './credential_access_root_console_failure_brute_force.json'; import rule213 from './initial_access_unsecure_elasticsearch_node.json'; @@ -300,15 +300,15 @@ import rule288 from './discovery_post_exploitation_public_ip_reconnaissance.json import rule289 from './initial_access_zoom_meeting_with_no_passcode.json'; import rule290 from './defense_evasion_gcp_logging_sink_deletion.json'; import rule291 from './defense_evasion_gcp_pub_sub_topic_deletion.json'; -import rule292 from './credential_access_gcp_iam_service_account_key_deletion.json'; -import rule293 from './credential_access_gcp_key_created_for_service_account.json'; -import rule294 from './defense_evasion_gcp_firewall_rule_created.json'; -import rule295 from './defense_evasion_gcp_firewall_rule_deleted.json'; -import rule296 from './defense_evasion_gcp_firewall_rule_modified.json'; -import rule297 from './defense_evasion_gcp_logging_bucket_deletion.json'; -import rule298 from './defense_evasion_gcp_storage_bucket_permissions_modified.json'; -import rule299 from './impact_gcp_storage_bucket_deleted.json'; -import rule300 from './initial_access_gcp_iam_custom_role_creation.json'; +import rule292 from './defense_evasion_gcp_firewall_rule_created.json'; +import rule293 from './defense_evasion_gcp_firewall_rule_deleted.json'; +import rule294 from './defense_evasion_gcp_firewall_rule_modified.json'; +import rule295 from './defense_evasion_gcp_logging_bucket_deletion.json'; +import rule296 from './defense_evasion_gcp_storage_bucket_permissions_modified.json'; +import rule297 from './impact_gcp_storage_bucket_deleted.json'; +import rule298 from './initial_access_gcp_iam_custom_role_creation.json'; +import rule299 from './persistence_gcp_iam_service_account_key_deletion.json'; +import rule300 from './persistence_gcp_key_created_for_service_account.json'; import rule301 from './defense_evasion_gcp_storage_bucket_configuration_modified.json'; import rule302 from './exfiltration_gcp_logging_sink_modification.json'; import rule303 from './impact_gcp_iam_role_deletion.json'; @@ -336,7 +336,7 @@ import rule324 from './persistence_ms_office_addins_file.json'; import rule325 from './discovery_adfind_command_activity.json'; import rule326 from './discovery_security_software_wmic.json'; import rule327 from './execution_command_shell_via_rundll32.json'; -import rule328 from './lateral_movement_suspicious_cmd_wmi.json'; +import rule328 from './execution_suspicious_cmd_wmi.json'; import rule329 from './lateral_movement_via_startup_folder_rdp_smb.json'; import rule330 from './privilege_escalation_uac_bypass_com_interface_icmluautil.json'; import rule331 from './privilege_escalation_uac_bypass_mock_windir.json'; @@ -344,7 +344,7 @@ import rule332 from './defense_evasion_potential_processherpaderping.json'; import rule333 from './privilege_escalation_uac_bypass_dll_sideloading.json'; import rule334 from './execution_shared_modules_local_sxs_dll.json'; import rule335 from './privilege_escalation_uac_bypass_com_clipup.json'; -import rule336 from './execution_via_explorer_suspicious_child_parent_args.json'; +import rule336 from './initial_access_via_explorer_suspicious_child_parent_args.json'; import rule337 from './execution_from_unusual_directory.json'; import rule338 from './execution_from_unusual_path_cmdline.json'; import rule339 from './credential_access_kerberoasting_unusual_process.json'; @@ -381,9 +381,9 @@ import rule369 from './credential_access_potential_ssh_bruteforce.json'; import rule370 from './credential_access_promt_for_pwd_via_osascript.json'; import rule371 from './lateral_movement_remote_services.json'; import rule372 from './application_added_to_google_workspace_domain.json'; -import rule373 from './defense_evasion_suspicious_powershell_imgload.json'; -import rule374 from './domain_added_to_google_workspace_trusted_domains.json'; -import rule375 from './execution_suspicious_image_load_wmi_ms_office.json'; +import rule373 from './domain_added_to_google_workspace_trusted_domains.json'; +import rule374 from './execution_suspicious_image_load_wmi_ms_office.json'; +import rule375 from './execution_suspicious_powershell_imgload.json'; import rule376 from './google_workspace_admin_role_deletion.json'; import rule377 from './google_workspace_mfa_enforcement_disabled.json'; import rule378 from './google_workspace_policy_modified.json'; @@ -434,7 +434,7 @@ import rule422 from './defense_evasion_port_forwarding_added_registry.json'; import rule423 from './lateral_movement_rdp_enabled_registry.json'; import rule424 from './privilege_escalation_printspooler_registry_copyfiles.json'; import rule425 from './privilege_escalation_rogue_windir_environment_var.json'; -import rule426 from './execution_scripts_process_started_via_wmi.json'; +import rule426 from './initial_access_scripts_process_started_via_wmi.json'; import rule427 from './command_and_control_iexplore_via_com.json'; import rule428 from './command_and_control_remote_file_copy_scripts.json'; import rule429 from './persistence_local_scheduled_task_scripting.json'; @@ -445,13 +445,13 @@ import rule433 from './microsoft_365_teams_custom_app_interaction_allowed.json'; import rule434 from './persistence_microsoft_365_teams_external_access_enabled.json'; import rule435 from './credential_access_microsoft_365_potential_password_spraying_attack.json'; import rule436 from './defense_evasion_stop_process_service_threshold.json'; -import rule437 from './defense_evasion_unusual_dir_ads.json'; -import rule438 from './discovery_admin_recon.json'; -import rule439 from './discovery_file_dir_discovery.json'; -import rule440 from './discovery_net_view.json'; -import rule441 from './discovery_query_registry_via_reg.json'; -import rule442 from './discovery_remote_system_discovery_commands_windows.json'; -import rule443 from './exfiltration_winrar_encryption.json'; +import rule437 from './collection_winrar_encryption.json'; +import rule438 from './defense_evasion_unusual_dir_ads.json'; +import rule439 from './discovery_admin_recon.json'; +import rule440 from './discovery_file_dir_discovery.json'; +import rule441 from './discovery_net_view.json'; +import rule442 from './discovery_query_registry_via_reg.json'; +import rule443 from './discovery_remote_system_discovery_commands_windows.json'; import rule444 from './persistence_via_windows_management_instrumentation_event_subscription.json'; import rule445 from './execution_scripting_osascript_exec_followed_by_netcon.json'; import rule446 from './execution_shell_execution_via_apple_scripting.json'; @@ -460,6 +460,16 @@ import rule448 from './persistence_creation_modif_launch_deamon_sequence.json'; import rule449 from './persistence_folder_action_scripts_runtime.json'; import rule450 from './persistence_login_logout_hooks_defaults.json'; import rule451 from './privilege_escalation_explicit_creds_via_apple_scripting.json'; +import rule452 from './command_and_control_sunburst_c2_activity_detected.json'; +import rule453 from './defense_evasion_azure_application_credential_modification.json'; +import rule454 from './defense_evasion_azure_service_principal_addition.json'; +import rule455 from './defense_evasion_solarwinds_backdoor_service_disabled_via_registry.json'; +import rule456 from './execution_apt_solarwinds_backdoor_child_cmd_powershell.json'; +import rule457 from './execution_apt_solarwinds_backdoor_unusual_child_processes.json'; +import rule458 from './initial_access_azure_active_directory_powershell_signin.json'; +import rule459 from './collection_email_powershell_exchange_mailbox.json'; +import rule460 from './collection_persistence_powershell_exch_mailbox_activesync_add_device.json'; +import rule461 from './execution_scheduled_task_powershell_source.json'; export const rawRules = [ rule1, @@ -913,4 +923,14 @@ export const rawRules = [ rule449, rule450, rule451, + rule452, + rule453, + rule454, + rule455, + rule456, + rule457, + rule458, + rule459, + rule460, + rule461, ]; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_powershell_signin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_powershell_signin.json new file mode 100644 index 0000000000000..bbd8986175962 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_powershell_signin.json @@ -0,0 +1,60 @@ +{ + "author": [ + "Elastic" + ], + "description": "Identifies a sign-in using the Azure Active Directory PowerShell module. PowerShell for Azure Active Directory allows for managing settings from the command line, which is intended for users who are members of an admin role.", + "false_positives": [ + "Sign-ins using PowerShell may be done by a system or network administrator. Verify whether the username, hostname, and/or resource name should be signing into your environment. Sign-ins from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." + ], + "from": "now-25m", + "index": [ + "filebeat-*", + "logs-azure*" + ], + "language": "kuery", + "license": "Elastic License", + "name": "Azure Active Directory PowerShell Sign-in", + "note": "The Azure Fleet Integration or Filebeat module must be enabled to use this rule.", + "query": "event.dataset:azure.signinlogs and azure.signinlogs.properties.app_display_name:\"Azure Active Directory PowerShell\" and azure.signinlogs.properties.token_issuer_type:AzureAD and event.outcome:(success or Success)", + "references": [ + "https://msrc-blog.microsoft.com/2020/12/13/customer-guidance-on-recent-nation-state-cyber-attacks/", + "https://docs.microsoft.com/en-us/microsoft-365/enterprise/connect-to-microsoft-365-powershell?view=o365-worldwide" + ], + "risk_score": 21, + "rule_id": "a605c51a-73ad-406d-bf3a-f24cc41d5c97", + "severity": "low", + "tags": [ + "Elastic", + "Cloud", + "Azure", + "Continuous Monitoring", + "SecOps", + "Identity and Access" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" + }, + "technique": [ + { + "id": "T1078", + "name": "Valid Accounts", + "reference": "https://attack.mitre.org/techniques/T1078/", + "subtechnique": [ + { + "id": "T1078.004", + "name": "Cloud Accounts", + "reference": "https://attack.mitre.org/techniques/T1078/004/" + } + ] + } + ] + } + ], + "type": "query", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_consent_grant_attack_via_azure_registered_application.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_consent_grant_attack_via_azure_registered_application.json index a2b89f6e82d23..d6e710da9f120 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_consent_grant_attack_via_azure_registered_application.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_consent_grant_attack_via_azure_registered_application.json @@ -5,13 +5,14 @@ "description": "Detects when a user grants permissions to an Azure-registered application or when an administrator grants tenant-wide permissions to an application. An adversary may create an Azure-registered application that requests access to data such as contact information, email, or documents.", "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Possible Consent Grant Attack via Azure-Registered Application", "note": "- The Azure Filebeat module must be enabled to use this rule.\n- In a consent grant attack, an attacker tricks an end user into granting a malicious application consent to access their data, usually via a phishing attack. After the malicious application has been granted consent, it has account-level access to data without the need for an organizational account.\n- Normal remediation steps, like resetting passwords for breached accounts or requiring Multi-Factor Authentication (MFA) on accounts, are not effective against this type of attack, since these are third-party applications and are external to the organization.\n- Security analysts should review the list of trusted applications for any suspicious items.\n", - "query": "event.dataset:(azure.activitylogs or azure.auditlogs or o365.audit) and ( azure.activitylogs.operation_name:\"Consent to application\" or azure.auditlogs.operation_name:\"Consent to application\" or o365.audit.Operation:\"Consent to application.\" ) and event.outcome:success", + "query": "event.dataset:(azure.activitylogs or azure.auditlogs or o365.audit) and ( azure.activitylogs.operation_name:\"Consent to application\" or azure.auditlogs.operation_name:\"Consent to application\" or o365.audit.Operation:\"Consent to application.\" ) and event.outcome:(Success or success)", "references": [ "https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/detect-and-remediate-illicit-consent-grants?view=o365-worldwide" ], @@ -36,9 +37,16 @@ }, "technique": [ { - "id": "T1192", - "name": "Spearphishing Link", - "reference": "https://attack.mitre.org/techniques/T1192/" + "id": "T1566", + "name": "Phishing", + "reference": "https://attack.mitre.org/techniques/T1566/", + "subtechnique": [ + { + "id": "T1566.002", + "name": "Spearphishing Link", + "reference": "https://attack.mitre.org/techniques/T1566/002/" + } + ] } ] }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_external_guest_user_invite.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_external_guest_user_invite.json index 455fc3c762978..1b8a54a20afb8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_external_guest_user_invite.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_external_guest_user_invite.json @@ -8,13 +8,14 @@ ], "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure External Guest User Invitation", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.auditlogs and azure.auditlogs.operation_name:\"Invite external user\" and azure.auditlogs.properties.target_resources.*.display_name:guest and event.outcome:Success", + "query": "event.dataset:azure.auditlogs and azure.auditlogs.operation_name:\"Invite external user\" and azure.auditlogs.properties.target_resources.*.display_name:guest and event.outcome:(Success or success)", "references": [ "https://docs.microsoft.com/en-us/azure/governance/policy/samples/cis-azure-1-1-0" ], @@ -62,5 +63,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_gcp_iam_custom_role_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_gcp_iam_custom_role_creation.json index ff7ad0e8d29a2..c55e241177b93 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_gcp_iam_custom_role_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_gcp_iam_custom_role_creation.json @@ -7,13 +7,14 @@ "Custom role creations may be done by a system or network administrator. Verify whether the user email, resource name, and/or hostname should be making changes in your environment. Role creations from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP IAM Custom Role Creation", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:google.iam.admin.v*.CreateRole and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:google.iam.admin.v*.CreateRole and event.outcome:success", "references": [ "https://cloud.google.com/iam/docs/understanding-custom-roles" ], @@ -61,5 +62,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_policy_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_policy_deletion.json index 44c88c3818e74..d669555a0d745 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_policy_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_policy_deletion.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_rule_mod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_rule_mod.json index d3d78127c63fe..9ad62bb3a85bf 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_rule_mod.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_rule_mod.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_safelinks_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_safelinks_disabled.json index 2f8fe344887fb..2d9eba96e3d52 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_safelinks_disabled.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_safelinks_disabled.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", @@ -26,7 +27,7 @@ "Elastic", "Cloud", "Microsoft 365", - "Continuous Monioring", + "Continuous Monitoring", "SecOps", "Identity and Access" ], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_script_executing_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_script_executing_powershell.json similarity index 66% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_script_executing_powershell.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_script_executing_powershell.json index 843cf322e5849..609cd860cac2e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_script_executing_powershell.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_script_executing_powershell.json @@ -26,19 +26,26 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0002", - "name": "Execution", - "reference": "https://attack.mitre.org/tactics/TA0002/" + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" }, "technique": [ { - "id": "T1193", - "name": "Spearphishing Attachment", - "reference": "https://attack.mitre.org/techniques/T1193/" + "id": "T1566", + "name": "Phishing", + "reference": "https://attack.mitre.org/techniques/T1566/", + "subtechnique": [ + { + "id": "T1566.001", + "name": "Spearphishing Attachment", + "reference": "https://attack.mitre.org/techniques/T1566/001/" + } + ] } ] } ], "type": "query", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_scripts_process_started_via_wmi.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_scripts_process_started_via_wmi.json similarity index 82% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_scripts_process_started_via_wmi.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_scripts_process_started_via_wmi.json index a6bf38f6880ae..8376bb7e62bd8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_scripts_process_started_via_wmi.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_scripts_process_started_via_wmi.json @@ -26,20 +26,22 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0002", - "name": "Execution", - "reference": "https://attack.mitre.org/tactics/TA0002/" + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" }, "technique": [ { - "id": "T1193", - "name": "Spearphishing Attachment", - "reference": "https://attack.mitre.org/techniques/T1193/" - }, - { - "id": "T1047", - "name": "Windows Management Instrumentation", - "reference": "https://attack.mitre.org/techniques/T1047/" + "id": "T1566", + "name": "Phishing", + "reference": "https://attack.mitre.org/techniques/T1566/", + "subtechnique": [ + { + "id": "T1566.001", + "name": "Spearphishing Attachment", + "reference": "https://attack.mitre.org/techniques/T1566/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_ms_office_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_office_child_process.json similarity index 81% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_ms_office_child_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_office_child_process.json index 03e759e0529ba..55fabcb9c4cbd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_ms_office_child_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_office_child_process.json @@ -26,15 +26,22 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0002", - "name": "Execution", - "reference": "https://attack.mitre.org/tactics/TA0002/" + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" }, "technique": [ { - "id": "T1193", - "name": "Spearphishing Attachment", - "reference": "https://attack.mitre.org/techniques/T1193/" + "id": "T1566", + "name": "Phishing", + "reference": "https://attack.mitre.org/techniques/T1566/", + "subtechnique": [ + { + "id": "T1566.001", + "name": "Spearphishing Attachment", + "reference": "https://attack.mitre.org/techniques/T1566/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_ms_outlook_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_outlook_child_process.json similarity index 76% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_ms_outlook_child_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_outlook_child_process.json index d5ee8fa818367..6b48abe5db533 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_ms_outlook_child_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_outlook_child_process.json @@ -26,19 +26,26 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0002", - "name": "Execution", - "reference": "https://attack.mitre.org/tactics/TA0002/" + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" }, "technique": [ { - "id": "T1193", - "name": "Spearphishing Attachment", - "reference": "https://attack.mitre.org/techniques/T1193/" + "id": "T1566", + "name": "Phishing", + "reference": "https://attack.mitre.org/techniques/T1566/", + "subtechnique": [ + { + "id": "T1566.001", + "name": "Spearphishing Attachment", + "reference": "https://attack.mitre.org/techniques/T1566/001/" + } + ] } ] } ], "type": "query", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_dns_service_children.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_children.json similarity index 95% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_dns_service_children.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_children.json index 52e67b0c7bcff..be5dd0d0f13ac 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_dns_service_children.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_children.json @@ -34,9 +34,9 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0002", - "name": "Execution", - "reference": "https://attack.mitre.org/tactics/TA0002/" + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" }, "technique": [ { @@ -48,5 +48,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_dns_service_file_writes.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_file_writes.json similarity index 94% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_dns_service_file_writes.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_file_writes.json index 38454b3de3c69..14677b533706f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_dns_service_file_writes.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_file_writes.json @@ -30,9 +30,9 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0002", - "name": "Execution", - "reference": "https://attack.mitre.org/tactics/TA0002/" + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" }, "technique": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_explorer_suspicious_child_parent_args.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_explorer_suspicious_child_parent_args.json similarity index 62% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_explorer_suspicious_child_parent_args.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_explorer_suspicious_child_parent_args.json index 001b2d4043b4d..6b197127bc22d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_explorer_suspicious_child_parent_args.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_explorer_suspicious_child_parent_args.json @@ -26,25 +26,27 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0002", - "name": "Execution", - "reference": "https://attack.mitre.org/tactics/TA0002/" + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" }, "technique": [ { - "id": "T1064", - "name": "Scripting", - "reference": "https://attack.mitre.org/techniques/T1064/" - }, - { - "id": "T1192", - "name": "Spearphishing Link", - "reference": "https://attack.mitre.org/techniques/T1192/" - }, - { - "id": "T1193", - "name": "Spearphishing Attachment", - "reference": "https://attack.mitre.org/techniques/T1193/" + "id": "T1566", + "name": "Phishing", + "reference": "https://attack.mitre.org/techniques/T1566/", + "subtechnique": [ + { + "id": "T1566.001", + "name": "Spearphishing Attachment", + "reference": "https://attack.mitre.org/techniques/T1566/001/" + }, + { + "id": "T1566.002", + "name": "Spearphishing Link", + "reference": "https://attack.mitre.org/techniques/T1566/002/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_system_manager.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_system_manager.json similarity index 76% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_system_manager.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_system_manager.json index 1e734bbc247ab..a6c335dbdbd04 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_system_manager.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_system_manager.json @@ -35,20 +35,22 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0002", - "name": "Execution", - "reference": "https://attack.mitre.org/tactics/TA0002/" + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" }, "technique": [ { - "id": "T1064", - "name": "Scripting", - "reference": "https://attack.mitre.org/techniques/T1064/" - }, - { - "id": "T1086", - "name": "PowerShell", - "reference": "https://attack.mitre.org/techniques/T1086/" + "id": "T1566", + "name": "Phishing", + "reference": "https://attack.mitre.org/techniques/T1566/", + "subtechnique": [ + { + "id": "T1566.002", + "name": "Spearphishing Link", + "reference": "https://attack.mitre.org/techniques/T1566/002/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_cmd_service.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_cmd_service.json index 148bd72f7c4be..db35602753ab0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_cmd_service.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_cmd_service.json @@ -35,20 +35,54 @@ "id": "T1021", "name": "Remote Services", "reference": "https://attack.mitre.org/techniques/T1021/" - }, + } + ] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0003", + "name": "Persistence", + "reference": "https://attack.mitre.org/tactics/TA0003/" + }, + "technique": [ { - "id": "T1050", - "name": "New Service", - "reference": "https://attack.mitre.org/techniques/T1050/" - }, + "id": "T1543", + "name": "Create or Modify System Process", + "reference": "https://attack.mitre.org/techniques/T1543/", + "subtechnique": [ + { + "id": "T1543.003", + "name": "Windows Service", + "reference": "https://attack.mitre.org/techniques/T1543/003/" + } + ] + } + ] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0002", + "name": "Execution", + "reference": "https://attack.mitre.org/tactics/TA0002/" + }, + "technique": [ { - "id": "T1035", - "name": "Service Execution", - "reference": "https://attack.mitre.org/techniques/T1035/" + "id": "T1569", + "name": "System Services", + "reference": "https://attack.mitre.org/techniques/T1569/", + "subtechnique": [ + { + "id": "T1569.002", + "name": "Service Execution", + "reference": "https://attack.mitre.org/techniques/T1569/002/" + } + ] } ] } ], "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_execution_via_file_shares_sequence.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_execution_via_file_shares_sequence.json index d0f301249017e..be4ad485fdbe4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_execution_via_file_shares_sequence.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_execution_via_file_shares_sequence.json @@ -35,9 +35,16 @@ }, "technique": [ { - "id": "T1077", - "name": "Windows Admin Shares", - "reference": "https://attack.mitre.org/techniques/T1077/" + "id": "T1021", + "name": "Remote Services", + "reference": "https://attack.mitre.org/techniques/T1021/", + "subtechnique": [ + { + "id": "T1021.002", + "name": "SMB/Windows Admin Shares", + "reference": "https://attack.mitre.org/techniques/T1021/002/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_wmi.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_wmi.json index 130c8d37ed853..e08c758f6f693 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_wmi.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_wmi.json @@ -30,6 +30,15 @@ "name": "Lateral Movement", "reference": "https://attack.mitre.org/tactics/TA0008/" }, + "technique": [] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0002", + "name": "Execution", + "reference": "https://attack.mitre.org/tactics/TA0002/" + }, "technique": [ { "id": "T1047", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_local_service_commands.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_local_service_commands.json similarity index 88% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_local_service_commands.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_local_service_commands.json index 693ca83e387b3..620be4c2cefb0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_local_service_commands.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_local_service_commands.json @@ -26,9 +26,9 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0002", - "name": "Execution", - "reference": "https://attack.mitre.org/tactics/TA0002/" + "id": "TA0008", + "name": "Lateral Movement", + "reference": "https://attack.mitre.org/tactics/TA0008/" }, "technique": [ { @@ -40,5 +40,5 @@ } ], "type": "query", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_mount_hidden_or_webdav_share_net.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_mount_hidden_or_webdav_share_net.json index 575b715239ad7..3618a9f4d38bc 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_mount_hidden_or_webdav_share_net.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_mount_hidden_or_webdav_share_net.json @@ -32,9 +32,16 @@ }, "technique": [ { - "id": "T1077", - "name": "Windows Admin Shares", - "reference": "https://attack.mitre.org/techniques/T1077/" + "id": "T1021", + "name": "Remote Services", + "reference": "https://attack.mitre.org/techniques/T1021/", + "subtechnique": [ + { + "id": "T1021.002", + "name": "SMB/Windows Admin Shares", + "reference": "https://attack.mitre.org/techniques/T1021/002/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_file_copy_hidden_share.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_file_copy_hidden_share.json index 06d07e92abe6c..51920b66070e6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_file_copy_hidden_share.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_file_copy_hidden_share.json @@ -32,9 +32,16 @@ }, "technique": [ { - "id": "T1077", - "name": "Windows Admin Shares", - "reference": "https://attack.mitre.org/techniques/T1077/" + "id": "T1021", + "name": "Remote Services", + "reference": "https://attack.mitre.org/techniques/T1021/", + "subtechnique": [ + { + "id": "T1021.002", + "name": "SMB/Windows Admin Shares", + "reference": "https://attack.mitre.org/techniques/T1021/002/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_services.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_services.json index fd9eeb9be8eb6..9d202cf61243d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_services.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_services.json @@ -33,9 +33,9 @@ }, "technique": [ { - "id": "T1035", - "name": "Service Execution", - "reference": "https://attack.mitre.org/techniques/T1035/" + "id": "T1021", + "name": "Remote Services", + "reference": "https://attack.mitre.org/techniques/T1021/" } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_via_startup_folder_rdp_smb.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_via_startup_folder_rdp_smb.json index 02f49c816d786..49a7a2f3941b2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_via_startup_folder_rdp_smb.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_via_startup_folder_rdp_smb.json @@ -50,9 +50,16 @@ }, "technique": [ { - "id": "T1060", - "name": "Registry Run Keys / Startup Folder", - "reference": "https://attack.mitre.org/techniques/T1060/" + "id": "T1547", + "name": "Boot or Logon Autostart Execution", + "reference": "https://attack.mitre.org/techniques/T1547/", + "subtechnique": [ + { + "id": "T1547.001", + "name": "Registry Run Keys / Startup Folder", + "reference": "https://attack.mitre.org/techniques/T1547/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/mfa_disabled_for_google_workspace_organization.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/mfa_disabled_for_google_workspace_organization.json index 68bb88edbed3e..78b2785561b1e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/mfa_disabled_for_google_workspace_organization.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/mfa_disabled_for_google_workspace_organization.json @@ -8,14 +8,15 @@ ], "from": "now-130m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-google_workspace*" ], "interval": "10m", "language": "kuery", "license": "Elastic License", "name": "MFA Disabled for Google Workspace Organization", "note": "### Important Information Regarding Google Workspace Event Lag Times\n- As per Google's documentation, Google Workspace administrators may observe lag times ranging from minutes up to 3 days between the time of an event's occurrence and the event being visible in the Google Workspace admin/audit logs.\n- This rule is configured to run every 10 minutes with a lookback time of 130 minutes.\n- To reduce the risk of false negatives, consider reducing the interval that the Google Workspace (formerly G Suite) Filebeat module polls Google's reporting API for new events.\n- By default, `var.interval` is set to 2 hours (2h). Consider changing this interval to a lower value, such as 10 minutes (10m).\n- See the following references for further information.\n - https://support.google.com/a/answer/7061566\n - https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-gsuite.html", - "query": "event.dataset:gsuite.admin and event.provider:admin and event.category:iam and event.action:(ENFORCE_STRONG_AUTHENTICATION or ALLOW_STRONG_AUTHENTICATION) and gsuite.admin.new_value:false", + "query": "event.dataset:(gsuite.admin or google_workspace.admin) and event.provider:admin and event.category:iam and event.action:(ENFORCE_STRONG_AUTHENTICATION or ALLOW_STRONG_AUTHENTICATION) and gsuite.admin.new_value:false", "risk_score": 47, "rule_id": "e555105c-ba6d-481f-82bb-9b633e7b4827", "severity": "medium", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/microsoft_365_exchange_dkim_signing_config_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/microsoft_365_exchange_dkim_signing_config_disabled.json index 227bbe1189fef..62d0960f10f6a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/microsoft_365_exchange_dkim_signing_config_disabled.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/microsoft_365_exchange_dkim_signing_config_disabled.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/microsoft_365_teams_custom_app_interaction_allowed.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/microsoft_365_teams_custom_app_interaction_allowed.json index 33f4bc886720c..595023f9c61f9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/microsoft_365_teams_custom_app_interaction_allowed.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/microsoft_365_teams_custom_app_interaction_allowed.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_linux_anomalous_kernel_module_arguments.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_linux_anomalous_kernel_module_arguments.json index 52a1d6dd5c60a..1b826c306b996 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_linux_anomalous_kernel_module_arguments.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_linux_anomalous_kernel_module_arguments.json @@ -35,13 +35,20 @@ }, "technique": [ { - "id": "T1215", - "name": "Kernel Modules and Extensions", - "reference": "https://attack.mitre.org/techniques/T1215/" + "id": "T1547", + "name": "Boot or Logon Autostart Execution", + "reference": "https://attack.mitre.org/techniques/T1547/", + "subtechnique": [ + { + "id": "T1547.006", + "name": "Kernel Modules and Extensions", + "reference": "https://attack.mitre.org/techniques/T1547/006/" + } + ] } ] } ], "type": "machine_learning", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json index 077147a8ed1a6..4b6e47179691b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1044", - "name": "File System Permissions Weakness", - "reference": "https://attack.mitre.org/techniques/T1044/" + "id": "T1574", + "name": "Hijack Execution Flow", + "reference": "https://attack.mitre.org/techniques/T1574/", + "subtechnique": [ + { + "id": "T1574.010", + "name": "Services File Permissions Weakness", + "reference": "https://attack.mitre.org/techniques/T1574/010/" + } + ] } ] } ], "type": "query", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_app_compat_shim.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_app_compat_shim.json index 5c467c39f5128..3e7bfb9f46ce5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_app_compat_shim.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_app_compat_shim.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1138", - "name": "Application Shimming", - "reference": "https://attack.mitre.org/techniques/T1138/" + "id": "T1546", + "name": "Event Triggered Execution", + "reference": "https://attack.mitre.org/techniques/T1546/", + "subtechnique": [ + { + "id": "T1546.011", + "name": "Application Shimming", + "reference": "https://attack.mitre.org/techniques/T1546/011/" + } + ] } ] } ], "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_appcertdlls_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_appcertdlls_registry.json index 8f2c14ed5018c..0d538ba55c1fd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_appcertdlls_registry.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_appcertdlls_registry.json @@ -31,9 +31,16 @@ }, "technique": [ { - "id": "T1182", - "name": "AppCert DLLs", - "reference": "https://attack.mitre.org/techniques/T1182/" + "id": "T1546", + "name": "Event Triggered Execution", + "reference": "https://attack.mitre.org/techniques/T1546/", + "subtechnique": [ + { + "id": "T1546.009", + "name": "AppCert DLLs", + "reference": "https://attack.mitre.org/techniques/T1546/009/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_appinitdlls_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_appinitdlls_registry.json index 174961449c6fc..d79248fd72ae5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_appinitdlls_registry.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_appinitdlls_registry.json @@ -31,9 +31,16 @@ }, "technique": [ { - "id": "T1103", - "name": "AppInit DLLs", - "reference": "https://attack.mitre.org/techniques/T1103/" + "id": "T1546", + "name": "Event Triggered Execution", + "reference": "https://attack.mitre.org/techniques/T1546/", + "subtechnique": [ + { + "id": "T1546.010", + "name": "AppInit DLLs", + "reference": "https://attack.mitre.org/techniques/T1546/010/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_account_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_account_created.json index 5c000967ce44d..92e1f0b9d165a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_account_created.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_account_created.json @@ -5,13 +5,14 @@ "description": "Identifies when an Azure Automation account is created. Azure Automation accounts can be used to automate management tasks and orchestrate actions across systems. An adversary may create an Automation account in order to maintain persistence in their target's environment.", "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Automation Account Created", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.AUTOMATION/AUTOMATIONACCOUNTS/WRITE and event.outcome:Success", + "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:MICROSOFT.AUTOMATION/AUTOMATIONACCOUNTS/WRITE and event.outcome:(Success or success)", "references": [ "https://powerzure.readthedocs.io/en/latest/Functions/operational.html#create-backdoor", "https://github.com/hausec/PowerZure", @@ -62,5 +63,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_runbook_created_or_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_runbook_created_or_modified.json index 28a5864353942..9d3df9076fb08 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_runbook_created_or_modified.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_runbook_created_or_modified.json @@ -5,13 +5,14 @@ "description": "Identifies when an Azure Automation runbook is created or modified. An adversary may create or modify an Azure Automation runbook to execute malicious code and maintain persistence in their target's environment.", "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Automation Runbook Created or Modified", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:(MICROSOFT.AUTOMATION/AUTOMATIONACCOUNTS/RUNBOOKS/DRAFT/WRITE or MICROSOFT.AUTOMATION/AUTOMATIONACCOUNTS/RUNBOOKS/WRITE or MICROSOFT.AUTOMATION/AUTOMATIONACCOUNTS/RUNBOOKS/PUBLISH/ACTION) and event.outcome:Success", + "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:(MICROSOFT.AUTOMATION/AUTOMATIONACCOUNTS/RUNBOOKS/DRAFT/WRITE or MICROSOFT.AUTOMATION/AUTOMATIONACCOUNTS/RUNBOOKS/WRITE or MICROSOFT.AUTOMATION/AUTOMATIONACCOUNTS/RUNBOOKS/PUBLISH/ACTION) and event.outcome:(Success or success)", "references": [ "https://powerzure.readthedocs.io/en/latest/Functions/operational.html#create-backdoor", "https://github.com/hausec/PowerZure", @@ -30,5 +31,5 @@ "Configuration Audit" ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_webhook_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_webhook_created.json index 5dde815022283..8141f3ade440c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_webhook_created.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_webhook_created.json @@ -5,13 +5,14 @@ "description": "Identifies when an Azure Automation webhook is created. Azure Automation runbooks can be configured to execute via a webhook. A webhook uses a custom URL passed to Azure Automation along with a data payload specific to the runbook. An adversary may create a webhook in order to trigger a runbook that contains malicious code.", "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Automation Webhook Created", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:(MICROSOFT.AUTOMATION/AUTOMATIONACCOUNTS/WEBHOOKS/ACTION or MICROSOFT.AUTOMATION/AUTOMATIONACCOUNTS/WEBHOOKS/WRITE) and event.outcome:Success", + "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:(MICROSOFT.AUTOMATION/AUTOMATIONACCOUNTS/WEBHOOKS/ACTION or MICROSOFT.AUTOMATION/AUTOMATIONACCOUNTS/WEBHOOKS/WRITE) and event.outcome:(Success or success)", "references": [ "https://powerzure.readthedocs.io/en/latest/Functions/operational.html#create-backdoor", "https://github.com/hausec/PowerZure", @@ -31,5 +32,5 @@ ], "to": "now-25m", "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_conditional_access_policy_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_conditional_access_policy_modified.json index 14d6d3d479c6a..935391de689c8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_conditional_access_policy_modified.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_conditional_access_policy_modified.json @@ -5,13 +5,14 @@ "description": "Identifies when an Azure Conditional Access policy is modified. Azure Conditional Access policies control access to resources via if-then statements. For example, if a user wants to access a resource, then they must complete an action such as using multi-factor authentication to access it. An adversary may modify a Conditional Access policy in order to weaken their target's security controls.", "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Conditional Access Policy Modified", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:(azure.activitylogs or azure.auditlogs) and ( azure.activitylogs.operation_name:\"Update policy\" or azure.auditlogs.operation_name:\"Update policy\" ) and event.outcome:success", + "query": "event.dataset:(azure.activitylogs or azure.auditlogs) and ( azure.activitylogs.operation_name:\"Update policy\" or azure.auditlogs.operation_name:\"Update policy\" ) and event.outcome:(Success or success)", "references": [ "https://docs.microsoft.com/en-us/azure/active-directory/conditional-access/overview" ], @@ -44,5 +45,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_pim_user_added_global_admin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_pim_user_added_global_admin.json index 24411a40ffc46..960c028d206b2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_pim_user_added_global_admin.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_pim_user_added_global_admin.json @@ -7,13 +7,14 @@ "Global administrator additions may be done by a system or network administrator. Verify whether the username, hostname, and/or resource name should be making changes in your environment. Global administrator additions from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Global Administrator Role Addition to PIM User", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.auditlogs and azure.auditlogs.properties.category:RoleManagement and azure.auditlogs.operation_name:(\"Add eligible member to role in PIM completed (permanent)\" or \"Add member to role in PIM completed (timebound)\") and azure.auditlogs.properties.target_resources.*.display_name:\"Global Administrator\" and event.outcome:Success", + "query": "event.dataset:azure.auditlogs and azure.auditlogs.properties.category:RoleManagement and azure.auditlogs.operation_name:(\"Add eligible member to role in PIM completed (permanent)\" or \"Add member to role in PIM completed (timebound)\") and azure.auditlogs.properties.target_resources.*.display_name:\"Global Administrator\" and event.outcome:(Success or success)", "references": [ "https://docs.microsoft.com/en-us/azure/active-directory/users-groups-roles/directory-assign-admin-roles" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_privileged_identity_management_role_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_privileged_identity_management_role_modified.json index 77e955727b2d8..e27f192fbf573 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_privileged_identity_management_role_modified.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_privileged_identity_management_role_modified.json @@ -5,13 +5,14 @@ "description": "Azure Active Directory (AD) Privileged Identity Management (PIM) is a service that enables you to manage, control, and monitor access to important resources in an organization. PIM can be used to manage the built-in Azure resource roles such as Global Administrator and Application Administrator. An adversary may add a user to a PIM role in order to maintain persistence in their target's environment or modify a PIM role to weaken their target's security controls.", "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Azure Privilege Identity Management Role Modified", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.auditlogs and azure.auditlogs.operation_name:\"Update role setting in PIM\" and event.outcome:Success", + "query": "event.dataset:azure.auditlogs and azure.auditlogs.operation_name:\"Update role setting in PIM\" and event.outcome:(Success or success)", "references": [ "https://docs.microsoft.com/en-us/azure/active-directory/privileged-identity-management/pim-resource-roles-assign-roles", "https://docs.microsoft.com/en-us/azure/active-directory/privileged-identity-management/pim-configure" @@ -60,5 +61,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_creation_change_launch_agents_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_creation_change_launch_agents_file.json index c54600fdf5f81..202259ebcfbe4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_creation_change_launch_agents_file.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_creation_change_launch_agents_file.json @@ -38,9 +38,16 @@ }, "technique": [ { - "id": "T1159", - "name": "Launch Agent", - "reference": "https://attack.mitre.org/techniques/T1159/" + "id": "T1543", + "name": "Create or Modify System Process", + "reference": "https://attack.mitre.org/techniques/T1543/", + "subtechnique": [ + { + "id": "T1543.001", + "name": "Launch Agent", + "reference": "https://attack.mitre.org/techniques/T1543/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_network_acl_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_network_acl_creation.json index 8deaa9924cc1d..7817915cc557d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_network_acl_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_network_acl_creation.json @@ -44,13 +44,13 @@ }, "technique": [ { - "id": "T1108", - "name": "Redundant Access", - "reference": "https://attack.mitre.org/techniques/T1108/" + "id": "T1133", + "name": "External Remote Services", + "reference": "https://attack.mitre.org/techniques/T1133/" } ] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_ifeo_injection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_ifeo_injection.json index 5fb49313154c4..6d607cfd96f23 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_ifeo_injection.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_ifeo_injection.json @@ -34,9 +34,16 @@ }, "technique": [ { - "id": "T1183", - "name": "Image File Execution Options Injection", - "reference": "https://attack.mitre.org/techniques/T1183/" + "id": "T1546", + "name": "Event Triggered Execution", + "reference": "https://attack.mitre.org/techniques/T1546/", + "subtechnique": [ + { + "id": "T1546.012", + "name": "Image File Execution Options Injection", + "reference": "https://attack.mitre.org/techniques/T1546/012/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_gcp_iam_service_account_key_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_iam_service_account_key_deletion.json similarity index 84% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_gcp_iam_service_account_key_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_iam_service_account_key_deletion.json index 5db891caa2857..0b6478cbeab9e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_gcp_iam_service_account_key_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_iam_service_account_key_deletion.json @@ -7,13 +7,14 @@ "Service account key deletions may be done by a system or network administrator. Verify whether the user email, resource name, and/or hostname should be making changes in your environment. Key deletions from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP IAM Service Account Key Deletion", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:google.iam.admin.v*.DeleteServiceAccountKey and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:google.iam.admin.v*.DeleteServiceAccountKey and event.outcome:success", "references": [ "https://cloud.google.com/iam/docs/service-accounts", "https://cloud.google.com/iam/docs/creating-managing-service-account-keys" @@ -33,9 +34,9 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0006", - "name": "Credential Access", - "reference": "https://attack.mitre.org/tactics/TA0006/" + "id": "TA0003", + "name": "Persistence", + "reference": "https://attack.mitre.org/tactics/TA0003/" }, "technique": [ { @@ -47,5 +48,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_gcp_key_created_for_service_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_key_created_for_service_account.json similarity index 84% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_gcp_key_created_for_service_account.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_key_created_for_service_account.json index a6d45b7465771..a8288d7f3c230 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_gcp_key_created_for_service_account.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_key_created_for_service_account.json @@ -7,13 +7,14 @@ "Service account keys may be created by system administrators. Verify that the configuration change was expected. Exceptions can be added to this rule to filter expected behavior." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Service Account Key Creation", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:google.iam.admin.v*.CreateServiceAccountKey and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:google.iam.admin.v*.CreateServiceAccountKey and event.outcome:success", "references": [ "https://cloud.google.com/iam/docs/service-accounts", "https://cloud.google.com/iam/docs/creating-managing-service-account-keys" @@ -33,9 +34,9 @@ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0006", - "name": "Credential Access", - "reference": "https://attack.mitre.org/tactics/TA0006/" + "id": "TA0003", + "name": "Persistence", + "reference": "https://attack.mitre.org/tactics/TA0003/" }, "technique": [ { @@ -47,5 +48,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_service_account_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_service_account_created.json index 62e28e588cd0a..2278d610927ec 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_service_account_created.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_service_account_created.json @@ -7,13 +7,14 @@ "Service accounts can be created by system administrators. Verify that the behavior was expected. Exceptions can be added to this rule to filter expected behavior." ], "index": [ - "filebeat-*" + "filebeat-*", + "logs-gcp*" ], "language": "kuery", "license": "Elastic License", "name": "GCP Service Account Creation", "note": "The GCP Filebeat module must be enabled to use this rule.", - "query": "event.dataset:googlecloud.audit and event.action:google.iam.admin.v*.CreateServiceAccount and event.outcome:success", + "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:google.iam.admin.v*.CreateServiceAccount and event.outcome:success", "references": [ "https://cloud.google.com/iam/docs/service-accounts" ], @@ -46,5 +47,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_admin_role_assigned_to_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_admin_role_assigned_to_user.json index 16f20b731dadb..c1876660185de 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_admin_role_assigned_to_user.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_admin_role_assigned_to_user.json @@ -8,14 +8,15 @@ ], "from": "now-130m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-google_workspace*" ], "interval": "10m", "language": "kuery", "license": "Elastic License", "name": "Google Workspace Admin Role Assigned to a User", "note": "### Important Information Regarding Google Workspace Event Lag Times\n- As per Google's documentation, Google Workspace administrators may observe lag times ranging from minutes up to 3 days between the time of an event's occurrence and the event being visible in the Google Workspace admin/audit logs.\n- This rule is configured to run every 10 minutes with a lookback time of 130 minutes.\n- To reduce the risk of false negatives, consider reducing the interval that the Google Workspace (formerly G Suite) Filebeat module polls Google's reporting API for new events.\n- By default, `var.interval` is set to 2 hours (2h). Consider changing this interval to a lower value, such as 10 minutes (10m).\n- See the following references for further information.\n - https://support.google.com/a/answer/7061566\n - https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-gsuite.html", - "query": "event.dataset:gsuite.admin and event.provider:admin and event.category:iam and event.action:ASSIGN_ROLE", + "query": "event.dataset:(gsuite.admin or google_workspace.admin) and event.provider:admin and event.category:iam and event.action:ASSIGN_ROLE", "references": [ "https://support.google.com/a/answer/172176?hl=en" ], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_api_access_granted_via_domain_wide_delegation_of_authority.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_api_access_granted_via_domain_wide_delegation_of_authority.json index 8ca413dc898d0..ef6fa5c1624b1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_api_access_granted_via_domain_wide_delegation_of_authority.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_api_access_granted_via_domain_wide_delegation_of_authority.json @@ -8,14 +8,15 @@ ], "from": "now-130m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-google_workspace*" ], "interval": "10m", "language": "kuery", "license": "Elastic License", "name": "Google Workspace API Access Granted via Domain-Wide Delegation of Authority", "note": "### Important Information Regarding Google Workspace Event Lag Times\n- As per Google's documentation, Google Workspace administrators may observe lag times ranging from minutes up to 3 days between the time of an event's occurrence and the event being visible in the Google Workspace admin/audit logs.\n- This rule is configured to run every 10 minutes with a lookback time of 130 minutes.\n- To reduce the risk of false negatives, consider reducing the interval that the Google Workspace (formerly G Suite) Filebeat module polls Google's reporting API for new events.\n- By default, `var.interval` is set to 2 hours (2h). Consider changing this interval to a lower value, such as 10 minutes (10m).\n- See the following references for further information.\n - https://support.google.com/a/answer/7061566\n - https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-gsuite.html", - "query": "event.dataset:gsuite.admin and event.provider:admin and event.category:iam and event.action:AUTHORIZE_API_CLIENT_ACCESS", + "query": "event.dataset:(gsuite.admin or google_workspace.admin) and event.provider:admin and event.category:iam and event.action:AUTHORIZE_API_CLIENT_ACCESS", "references": [ "https://developers.google.com/admin-sdk/directory/v1/guides/delegation" ], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_custom_admin_role_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_custom_admin_role_created.json index 0b98ba7de8063..8886cc1863771 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_custom_admin_role_created.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_custom_admin_role_created.json @@ -8,14 +8,15 @@ ], "from": "now-130m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-google_workspace*" ], "interval": "10m", "language": "kuery", "license": "Elastic License", "name": "Google Workspace Custom Admin Role Created", "note": "### Important Information Regarding Google Workspace Event Lag Times\n- As per Google's documentation, Google Workspace administrators may observe lag times ranging from minutes up to 3 days between the time of an event's occurrence and the event being visible in the Google Workspace admin/audit logs.\n- This rule is configured to run every 10 minutes with a lookback time of 130 minutes.\n- To reduce the risk of false negatives, consider reducing the interval that the Google Workspace (formerly G Suite) Filebeat module polls Google's reporting API for new events.\n- By default, `var.interval` is set to 2 hours (2h). Consider changing this interval to a lower value, such as 10 minutes (10m).\n- See the following references for further information.\n - https://support.google.com/a/answer/7061566\n - https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-gsuite.html", - "query": "event.dataset:gsuite.admin and event.provider:admin and event.category:iam and event.action:CREATE_ROLE", + "query": "event.dataset:(gsuite.admin or google_workspace.admin) and event.provider:admin and event.category:iam and event.action:CREATE_ROLE", "references": [ "https://support.google.com/a/answer/2406043?hl=en" ], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_role_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_role_modified.json index d8c344cc0e0ba..5669d61223312 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_role_modified.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_role_modified.json @@ -8,14 +8,15 @@ ], "from": "now-130m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-google_workspace*" ], "interval": "10m", "language": "kuery", "license": "Elastic License", "name": "Google Workspace Role Modified", "note": "### Important Information Regarding Google Workspace Event Lag Times\n- As per Google's documentation, Google Workspace administrators may observe lag times ranging from minutes up to 3 days between the time of an event's occurrence and the event being visible in the Google Workspace admin/audit logs.\n- This rule is configured to run every 10 minutes with a lookback time of 130 minutes.\n- To reduce the risk of false negatives, consider reducing the interval that the Google Workspace (formerly G Suite) Filebeat module polls Google's reporting API for new events.\n- By default, `var.interval` is set to 2 hours (2h). Consider changing this interval to a lower value, such as 10 minutes (10m).\n- See the following references for further information.\n - https://support.google.com/a/answer/7061566\n - https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-gsuite.html", - "query": "event.dataset:gsuite.admin and event.provider:admin and event.category:iam and event.action:(ADD_PRIVILEGE or UPDATE_ROLE)", + "query": "event.dataset:(gsuite.admin or google_workspace.admin) and event.provider:admin and event.category:iam and event.action:(ADD_PRIVILEGE or UPDATE_ROLE)", "references": [ "https://support.google.com/a/answer/2406043?hl=en" ], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json index 536eda4e21476..f4ce907654855 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json @@ -37,23 +37,8 @@ "reference": "https://attack.mitre.org/techniques/T1053/" } ] - }, - { - "framework": "MITRE ATT&CK", - "tactic": { - "id": "TA0002", - "name": "Execution", - "reference": "https://attack.mitre.org/tactics/TA0002/" - }, - "technique": [ - { - "id": "T1021", - "name": "Remote Services", - "reference": "https://attack.mitre.org/techniques/T1021/" - } - ] } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_iam_group_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_iam_group_creation.json index 963ac46b7ed94..e5a793a1c9dce 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_iam_group_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_iam_group_creation.json @@ -42,13 +42,20 @@ }, "technique": [ { - "id": "T1108", - "name": "Redundant Access", - "reference": "https://attack.mitre.org/techniques/T1108/" + "id": "T1136", + "name": "Create Account", + "reference": "https://attack.mitre.org/techniques/T1136/", + "subtechnique": [ + { + "id": "T1136.003", + "name": "Cloud Account", + "reference": "https://attack.mitre.org/techniques/T1136/003/" + } + ] } ] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_kernel_module_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_kernel_module_activity.json index b29a8b2384f95..1ca6fc0709fdd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_kernel_module_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_kernel_module_activity.json @@ -38,13 +38,20 @@ }, "technique": [ { - "id": "T1215", - "name": "Kernel Modules and Extensions", - "reference": "https://attack.mitre.org/techniques/T1215/" + "id": "T1547", + "name": "Boot or Logon Autostart Execution", + "reference": "https://attack.mitre.org/techniques/T1547/", + "subtechnique": [ + { + "id": "T1547.006", + "name": "Kernel Modules and Extensions", + "reference": "https://attack.mitre.org/techniques/T1547/006/" + } + ] } ] } ], "type": "query", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_mfa_disabled_for_azure_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_mfa_disabled_for_azure_user.json index 8a9f4d4c661e9..c4d651fdfbe64 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_mfa_disabled_for_azure_user.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_mfa_disabled_for_azure_user.json @@ -5,13 +5,14 @@ "description": "Identifies when multi-factor authentication (MFA) is disabled for an Azure user account. An adversary may disable MFA for a user account in order to weaken the authentication requirements for the account.", "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "Multi-Factor Authentication Disabled for an Azure User", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.auditlogs and azure.auditlogs.operation_name:\"Disable Strong Authentication\" and event.outcome:Success", + "query": "event.dataset:azure.auditlogs and azure.auditlogs.operation_name:\"Disable Strong Authentication\" and event.outcome:(Success or success)", "risk_score": 47, "rule_id": "dafa3235-76dc-40e2-9f71-1773b96d24cf", "severity": "medium", @@ -41,5 +42,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_exchange_management_role_assignment.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_exchange_management_role_assignment.json index 851cfeb502e24..3d823012045c4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_exchange_management_role_assignment.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_exchange_management_role_assignment.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_teams_external_access_enabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_teams_external_access_enabled.json index 350f775e48a58..6a82e7677b657 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_teams_external_access_enabled.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_teams_external_access_enabled.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_teams_guest_access_enabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_teams_guest_access_enabled.json index 69de0fce7dfc6..4b90543d781e9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_teams_guest_access_enabled.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_teams_guest_access_enabled.json @@ -8,7 +8,8 @@ ], "from": "now-30m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-o365*" ], "language": "kuery", "license": "Elastic License", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_priv_escalation_via_accessibility_features.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_priv_escalation_via_accessibility_features.json index c915dc79da65a..e15fc903977f5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_priv_escalation_via_accessibility_features.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_priv_escalation_via_accessibility_features.json @@ -34,9 +34,16 @@ }, "technique": [ { - "id": "T1015", - "name": "Accessibility Features", - "reference": "https://attack.mitre.org/techniques/T1015/" + "id": "T1546", + "name": "Event Triggered Execution", + "reference": "https://attack.mitre.org/techniques/T1546/", + "subtechnique": [ + { + "id": "T1546.008", + "name": "Accessibility Features", + "reference": "https://attack.mitre.org/techniques/T1546/008/" + } + ] } ] }, @@ -49,9 +56,16 @@ }, "technique": [ { - "id": "T1015", - "name": "Accessibility Features", - "reference": "https://attack.mitre.org/techniques/T1015/" + "id": "T1546", + "name": "Event Triggered Execution", + "reference": "https://attack.mitre.org/techniques/T1546/", + "subtechnique": [ + { + "id": "T1546.008", + "name": "Accessibility Features", + "reference": "https://attack.mitre.org/techniques/T1546/008/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_cluster_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_cluster_creation.json index 06ca022726aad..577d6508e5453 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_cluster_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_cluster_creation.json @@ -44,9 +44,9 @@ }, "technique": [ { - "id": "T1108", - "name": "Redundant Access", - "reference": "https://attack.mitre.org/techniques/T1108/" + "id": "T1133", + "name": "External Remote Services", + "reference": "https://attack.mitre.org/techniques/T1133/" } ] }, @@ -57,15 +57,9 @@ "name": "Defense Evasion", "reference": "https://attack.mitre.org/tactics/TA0005/" }, - "technique": [ - { - "id": "T1108", - "name": "Redundant Access", - "reference": "https://attack.mitre.org/techniques/T1108/" - } - ] + "technique": [] } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_registry_uncommon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_registry_uncommon.json index c539ccfab16ed..2a4ef533a8477 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_registry_uncommon.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_registry_uncommon.json @@ -32,6 +32,15 @@ "name": "Persistence", "reference": "https://attack.mitre.org/tactics/TA0003/" }, + "technique": [] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0005", + "name": "Defense Evasion", + "reference": "https://attack.mitre.org/tactics/TA0005/" + }, "technique": [ { "id": "T1112", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_run_key_and_startup_broad.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_run_key_and_startup_broad.json index 19f8566ec0258..6f7a78dab6ad5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_run_key_and_startup_broad.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_run_key_and_startup_broad.json @@ -31,9 +31,16 @@ }, "technique": [ { - "id": "T1060", - "name": "Registry Run Keys / Startup Folder", - "reference": "https://attack.mitre.org/techniques/T1060/" + "id": "T1547", + "name": "Boot or Logon Autostart Execution", + "reference": "https://attack.mitre.org/techniques/T1547/", + "subtechnique": [ + { + "id": "T1547.001", + "name": "Registry Run Keys / Startup Folder", + "reference": "https://attack.mitre.org/techniques/T1547/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_runtime_run_key_startup_susp_procs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_runtime_run_key_startup_susp_procs.json index ea2e3727b3d23..52d0720839f5c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_runtime_run_key_startup_susp_procs.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_runtime_run_key_startup_susp_procs.json @@ -31,9 +31,16 @@ }, "technique": [ { - "id": "T1060", - "name": "Registry Run Keys / Startup Folder", - "reference": "https://attack.mitre.org/techniques/T1060/" + "id": "T1547", + "name": "Boot or Logon Autostart Execution", + "reference": "https://attack.mitre.org/techniques/T1547/", + "subtechnique": [ + { + "id": "T1547.001", + "name": "Registry Run Keys / Startup Folder", + "reference": "https://attack.mitre.org/techniques/T1547/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_services_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_services_registry.json index d6ca742d89b49..eabe4925a965e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_services_registry.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_services_registry.json @@ -31,9 +31,16 @@ }, "technique": [ { - "id": "T1050", - "name": "New Service", - "reference": "https://attack.mitre.org/techniques/T1050/" + "id": "T1543", + "name": "Create or Modify System Process", + "reference": "https://attack.mitre.org/techniques/T1543/", + "subtechnique": [ + { + "id": "T1543.003", + "name": "Windows Service", + "reference": "https://attack.mitre.org/techniques/T1543/003/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_activity_by_web_server.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_activity_by_web_server.json index ea10fa9bdf865..d6dfd63eef199 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_activity_by_web_server.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_activity_by_web_server.json @@ -38,13 +38,20 @@ }, "technique": [ { - "id": "T1100", - "name": "Web Shell", - "reference": "https://attack.mitre.org/techniques/T1100/" + "id": "T1505", + "name": "Server Software Component", + "reference": "https://attack.mitre.org/techniques/T1505/", + "subtechnique": [ + { + "id": "T1505.003", + "name": "Web Shell", + "reference": "https://attack.mitre.org/techniques/T1505/003/" + } + ] } ] } ], "type": "query", - "version": 6 + "version": 7 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_suspicious_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_suspicious_process.json index 7a398dad485d2..1e35cf3db6a98 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_suspicious_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_suspicious_process.json @@ -31,9 +31,16 @@ }, "technique": [ { - "id": "T1060", - "name": "Registry Run Keys / Startup Folder", - "reference": "https://attack.mitre.org/techniques/T1060/" + "id": "T1547", + "name": "Boot or Logon Autostart Execution", + "reference": "https://attack.mitre.org/techniques/T1547/", + "subtechnique": [ + { + "id": "T1547.001", + "name": "Registry Run Keys / Startup Folder", + "reference": "https://attack.mitre.org/techniques/T1547/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_unsigned_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_unsigned_process.json index f9410f73ad61a..67c9c3db6ba2a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_unsigned_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_unsigned_process.json @@ -30,9 +30,16 @@ }, "technique": [ { - "id": "T1060", - "name": "Registry Run Keys / Startup Folder", - "reference": "https://attack.mitre.org/techniques/T1060/" + "id": "T1547", + "name": "Boot or Logon Autostart Execution", + "reference": "https://attack.mitre.org/techniques/T1547/", + "subtechnique": [ + { + "id": "T1547.001", + "name": "Registry Run Keys / Startup Folder", + "reference": "https://attack.mitre.org/techniques/T1547/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_scripts.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_scripts.json index 607cc7c8030dc..ed462cb1145ad 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_scripts.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_scripts.json @@ -10,7 +10,7 @@ "language": "eql", "license": "Elastic License", "name": "Persistent Scripts in the Startup Directory", - "query": "file where event.type != \"deletion\" and user.domain != \"NT AUTHORITY\"\n and (\n // detect shortcuts created by wscript.exe or cscript.exe\n file.path : \"C:\\\\*\\\\Programs\\\\Startup\\\\*.lnk\" and\n process.name : (\"wscript.exe\", \"cscript.exe\")\n ) or\n // detect vbs or js files created by any process\n file.path : (\"C:\\\\*\\\\Programs\\\\Startup\\\\*.vbs\", \n \"C:\\\\*\\\\Programs\\\\Startup\\\\*.vbe\", \n \"C:\\\\*\\\\Programs\\\\Startup\\\\*.wsh\", \n \"C:\\\\*\\\\Programs\\\\Startup\\\\*.wsf\", \n \"C:\\\\*\\\\Programs\\\\Startup\\\\*.js\")\n", + "query": "file where event.type != \"deletion\" and user.domain != \"NT AUTHORITY\" and\n \n /* detect shortcuts created by wscript.exe or cscript.exe */\n (file.path : \"C:\\\\*\\\\Programs\\\\Startup\\\\*.lnk\" and\n process.name : (\"wscript.exe\", \"cscript.exe\")) or\n\n /* detect vbs or js files created by any process */\n file.path : (\"C:\\\\*\\\\Programs\\\\Startup\\\\*.vbs\", \n \"C:\\\\*\\\\Programs\\\\Startup\\\\*.vbe\", \n \"C:\\\\*\\\\Programs\\\\Startup\\\\*.wsh\", \n \"C:\\\\*\\\\Programs\\\\Startup\\\\*.wsf\", \n \"C:\\\\*\\\\Programs\\\\Startup\\\\*.js\")\n", "risk_score": 47, "rule_id": "f7c4dc5a-a58d-491d-9f14-9b66507121c0", "severity": "medium", @@ -31,9 +31,16 @@ }, "technique": [ { - "id": "T1060", - "name": "Registry Run Keys / Startup Folder", - "reference": "https://attack.mitre.org/techniques/T1060/" + "id": "T1547", + "name": "Boot or Logon Autostart Execution", + "reference": "https://attack.mitre.org/techniques/T1547/", + "subtechnique": [ + { + "id": "T1547.001", + "name": "Registry Run Keys / Startup Folder", + "reference": "https://attack.mitre.org/techniques/T1547/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_com_hijack_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_com_hijack_registry.json index 117a5108d2cab..762c439b84c7f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_com_hijack_registry.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_com_hijack_registry.json @@ -34,9 +34,16 @@ }, "technique": [ { - "id": "T1122", - "name": "Component Object Model Hijacking", - "reference": "https://attack.mitre.org/techniques/T1122/" + "id": "T1546", + "name": "Event Triggered Execution", + "reference": "https://attack.mitre.org/techniques/T1546/", + "subtechnique": [ + { + "id": "T1546.015", + "name": "Component Object Model Hijacking", + "reference": "https://attack.mitre.org/techniques/T1546/015/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_service_created_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_service_created_registry.json index 6fea602025f46..43db3b5a7afad 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_service_created_registry.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_service_created_registry.json @@ -31,9 +31,16 @@ }, "technique": [ { - "id": "T1050", - "name": "New Service", - "reference": "https://attack.mitre.org/techniques/T1050/" + "id": "T1543", + "name": "Create or Modify System Process", + "reference": "https://attack.mitre.org/techniques/T1543/", + "subtechnique": [ + { + "id": "T1543.003", + "name": "Windows Service", + "reference": "https://attack.mitre.org/techniques/T1543/003/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json index 880101e8d9338..e5040d2e6f29f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1050", - "name": "New Service", - "reference": "https://attack.mitre.org/techniques/T1050/" + "id": "T1543", + "name": "Create or Modify System Process", + "reference": "https://attack.mitre.org/techniques/T1543/", + "subtechnique": [ + { + "id": "T1543.003", + "name": "Windows Service", + "reference": "https://attack.mitre.org/techniques/T1543/003/" + } + ] } ] } ], "type": "query", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_added_as_owner_for_azure_application.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_added_as_owner_for_azure_application.json index 3fddde78beb33..05db850f69401 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_added_as_owner_for_azure_application.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_added_as_owner_for_azure_application.json @@ -5,13 +5,14 @@ "description": "Identifies when a user is added as an owner for an Azure application. An adversary may add a user account as an owner for an Azure application in order to grant additional permissions and modify the application's configuration using another account.", "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "User Added as Owner for Azure Application", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.auditlogs and azure.auditlogs.operation_name:\"Add owner to application\" and event.outcome:Success", + "query": "event.dataset:azure.auditlogs and azure.auditlogs.operation_name:\"Add owner to application\" and event.outcome:(Success or success)", "risk_score": 21, "rule_id": "774f5e28-7b75-4a58-b94e-41bf060fdd86", "severity": "low", @@ -41,5 +42,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_added_as_owner_for_azure_service_principal.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_added_as_owner_for_azure_service_principal.json index de6482f14d2f0..03f10d38bcefb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_added_as_owner_for_azure_service_principal.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_added_as_owner_for_azure_service_principal.json @@ -5,13 +5,14 @@ "description": "Identifies when a user is added as an owner for an Azure service principal. The service principal object defines what the application can do in the specific tenant, who can access the application, and what resources the app can access. A service principal object is created when an application is given permission to access resources in a tenant. An adversary may add a user account as an owner for a service principal and use that account in order to define what an application can do in the Azure AD tenant.", "from": "now-25m", "index": [ - "filebeat-*" + "filebeat-*", + "logs-azure*" ], "language": "kuery", "license": "Elastic License", "name": "User Added as Owner for Azure Service Principal", "note": "The Azure Filebeat module must be enabled to use this rule.", - "query": "event.dataset:azure.auditlogs and azure.auditlogs.operation_name:\"Add owner to service principal\" and event.outcome:Success", + "query": "event.dataset:azure.auditlogs and azure.auditlogs.operation_name:\"Add owner to service principal\" and event.outcome:(Success or success)", "references": [ "https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals" ], @@ -44,5 +45,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_application_shimming.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_application_shimming.json index c9d56a9c68edb..57a95969dedec 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_application_shimming.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_application_shimming.json @@ -31,9 +31,16 @@ }, "technique": [ { - "id": "T1138", - "name": "Application Shimming", - "reference": "https://attack.mitre.org/techniques/T1138/" + "id": "T1546", + "name": "Event Triggered Execution", + "reference": "https://attack.mitre.org/techniques/T1546/", + "subtechnique": [ + { + "id": "T1546.011", + "name": "Application Shimming", + "reference": "https://attack.mitre.org/techniques/T1546/011/" + } + ] } ] }, @@ -46,13 +53,20 @@ }, "technique": [ { - "id": "T1138", - "name": "Application Shimming", - "reference": "https://attack.mitre.org/techniques/T1138/" + "id": "T1546", + "name": "Event Triggered Execution", + "reference": "https://attack.mitre.org/techniques/T1546/", + "subtechnique": [ + { + "id": "T1546.011", + "name": "Application Shimming", + "reference": "https://attack.mitre.org/techniques/T1546/011/" + } + ] } ] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_hidden_run_key_valuename.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_hidden_run_key_valuename.json index 97bd9efa161e6..8d96c77ae11b4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_hidden_run_key_valuename.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_hidden_run_key_valuename.json @@ -36,9 +36,16 @@ }, "technique": [ { - "id": "T1060", - "name": "Registry Run Keys / Startup Folder", - "reference": "https://attack.mitre.org/techniques/T1060/" + "id": "T1547", + "name": "Boot or Logon Autostart Execution", + "reference": "https://attack.mitre.org/techniques/T1547/", + "subtechnique": [ + { + "id": "T1547.001", + "name": "Registry Run Keys / Startup Folder", + "reference": "https://attack.mitre.org/techniques/T1547/001/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_lsa_security_support_provider_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_lsa_security_support_provider_registry.json index c1a0beb2e1fde..3b00e09538716 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_lsa_security_support_provider_registry.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_lsa_security_support_provider_registry.json @@ -31,9 +31,16 @@ }, "technique": [ { - "id": "T1101", - "name": "Security Support Provider", - "reference": "https://attack.mitre.org/techniques/T1101/" + "id": "T1547", + "name": "Boot or Logon Autostart Execution", + "reference": "https://attack.mitre.org/techniques/T1547/", + "subtechnique": [ + { + "id": "T1547.005", + "name": "Security Support Provider", + "reference": "https://attack.mitre.org/techniques/T1547/005/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_update_orchestrator_service_hijack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_update_orchestrator_service_hijack.json index bdddf2eb7e8c7..a2d0aac843170 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_update_orchestrator_service_hijack.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_update_orchestrator_service_hijack.json @@ -35,13 +35,20 @@ }, "technique": [ { - "id": "T1050", - "name": "New Service", - "reference": "https://attack.mitre.org/techniques/T1050/" + "id": "T1543", + "name": "Create or Modify System Process", + "reference": "https://attack.mitre.org/techniques/T1543/", + "subtechnique": [ + { + "id": "T1543.003", + "name": "Windows Service", + "reference": "https://attack.mitre.org/techniques/T1543/003/" + } + ] } ] } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_rogue_windir_environment_var.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_rogue_windir_environment_var.json index 6ad1d8f89fcdd..044a6d0364be7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_rogue_windir_environment_var.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_rogue_windir_environment_var.json @@ -34,9 +34,16 @@ }, "technique": [ { - "id": "T1034", - "name": "Path Interception", - "reference": "https://attack.mitre.org/techniques/T1034/" + "id": "T1574", + "name": "Hijack Execution Flow", + "reference": "https://attack.mitre.org/techniques/T1574/", + "subtechnique": [ + { + "id": "T1574.007", + "name": "Path Interception by PATH Environment Variable", + "reference": "https://attack.mitre.org/techniques/T1574/007/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setgid_bit_set_via_chmod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setgid_bit_set_via_chmod.json index ff63d1e38d950..37dad90ff28a5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setgid_bit_set_via_chmod.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setgid_bit_set_via_chmod.json @@ -33,9 +33,16 @@ }, "technique": [ { - "id": "T1166", - "name": "Setuid and Setgid", - "reference": "https://attack.mitre.org/techniques/T1166/" + "id": "T1548", + "name": "Abuse Elevation Control Mechanism", + "reference": "https://attack.mitre.org/techniques/T1548/", + "subtechnique": [ + { + "id": "T1548.001", + "name": "Setuid and Setgid", + "reference": "https://attack.mitre.org/techniques/T1548/001/" + } + ] } ] }, @@ -46,15 +53,9 @@ "name": "Persistence", "reference": "https://attack.mitre.org/tactics/TA0003/" }, - "technique": [ - { - "id": "T1166", - "name": "Setuid and Setgid", - "reference": "https://attack.mitre.org/techniques/T1166/" - } - ] + "technique": [] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setuid_bit_set_via_chmod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setuid_bit_set_via_chmod.json index 47490fe08ff12..5f7e18f96d8f7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setuid_bit_set_via_chmod.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setuid_bit_set_via_chmod.json @@ -33,9 +33,16 @@ }, "technique": [ { - "id": "T1166", - "name": "Setuid and Setgid", - "reference": "https://attack.mitre.org/techniques/T1166/" + "id": "T1548", + "name": "Abuse Elevation Control Mechanism", + "reference": "https://attack.mitre.org/techniques/T1548/", + "subtechnique": [ + { + "id": "T1548.001", + "name": "Setuid and Setgid", + "reference": "https://attack.mitre.org/techniques/T1548/001/" + } + ] } ] }, @@ -46,15 +53,9 @@ "name": "Persistence", "reference": "https://attack.mitre.org/tactics/TA0003/" }, - "technique": [ - { - "id": "T1166", - "name": "Setuid and Setgid", - "reference": "https://attack.mitre.org/techniques/T1166/" - } - ] + "technique": [] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sudoers_file_mod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sudoers_file_mod.json index 5519f6ce3a9ec..14cbd8a8c51f6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sudoers_file_mod.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sudoers_file_mod.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1169", - "name": "Sudo", - "reference": "https://attack.mitre.org/techniques/T1169/" + "id": "T1548", + "name": "Abuse Elevation Control Mechanism", + "reference": "https://attack.mitre.org/techniques/T1548/", + "subtechnique": [ + { + "id": "T1548.003", + "name": "Sudo and Sudo Caching", + "reference": "https://attack.mitre.org/techniques/T1548/003/" + } + ] } ] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_clipup.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_clipup.json index 2a1749d04fdfe..c90187e5ba839 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_clipup.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_clipup.json @@ -35,9 +35,16 @@ }, "technique": [ { - "id": "T1088", - "name": "Bypass User Account Control", - "reference": "https://attack.mitre.org/techniques/T1088/" + "id": "T1548", + "name": "Abuse Elevation Control Mechanism", + "reference": "https://attack.mitre.org/techniques/T1548/", + "subtechnique": [ + { + "id": "T1548.002", + "name": "Bypass User Access Control", + "reference": "https://attack.mitre.org/techniques/T1548/002/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_ieinstal.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_ieinstal.json index 410124fdd699f..d1591f2af3430 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_ieinstal.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_ieinstal.json @@ -35,9 +35,16 @@ }, "technique": [ { - "id": "T1088", - "name": "Bypass User Account Control", - "reference": "https://attack.mitre.org/techniques/T1088/" + "id": "T1548", + "name": "Abuse Elevation Control Mechanism", + "reference": "https://attack.mitre.org/techniques/T1548/", + "subtechnique": [ + { + "id": "T1548.002", + "name": "Bypass User Access Control", + "reference": "https://attack.mitre.org/techniques/T1548/002/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_interface_icmluautil.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_interface_icmluautil.json index 9f5cdfffa57c7..b5aad5c1683db 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_interface_icmluautil.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_interface_icmluautil.json @@ -32,9 +32,16 @@ }, "technique": [ { - "id": "T1088", - "name": "Bypass User Account Control", - "reference": "https://attack.mitre.org/techniques/T1088/" + "id": "T1548", + "name": "Abuse Elevation Control Mechanism", + "reference": "https://attack.mitre.org/techniques/T1548/", + "subtechnique": [ + { + "id": "T1548.002", + "name": "Bypass User Access Control", + "reference": "https://attack.mitre.org/techniques/T1548/002/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_diskcleanup_hijack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_diskcleanup_hijack.json index 50774166af698..3d15242c7bf55 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_diskcleanup_hijack.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_diskcleanup_hijack.json @@ -32,9 +32,16 @@ }, "technique": [ { - "id": "T1088", - "name": "Bypass User Account Control", - "reference": "https://attack.mitre.org/techniques/T1088/" + "id": "T1548", + "name": "Abuse Elevation Control Mechanism", + "reference": "https://attack.mitre.org/techniques/T1548/", + "subtechnique": [ + { + "id": "T1548.002", + "name": "Bypass User Access Control", + "reference": "https://attack.mitre.org/techniques/T1548/002/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_dll_sideloading.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_dll_sideloading.json index 5ad7ca602a36a..e4cddc971568b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_dll_sideloading.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_dll_sideloading.json @@ -35,9 +35,16 @@ }, "technique": [ { - "id": "T1088", - "name": "Bypass User Account Control", - "reference": "https://attack.mitre.org/techniques/T1088/" + "id": "T1548", + "name": "Abuse Elevation Control Mechanism", + "reference": "https://attack.mitre.org/techniques/T1548/", + "subtechnique": [ + { + "id": "T1548.002", + "name": "Bypass User Access Control", + "reference": "https://attack.mitre.org/techniques/T1548/002/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json index 415111c725828..9946ab2565b7e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json @@ -32,13 +32,20 @@ }, "technique": [ { - "id": "T1088", - "name": "Bypass User Account Control", - "reference": "https://attack.mitre.org/techniques/T1088/" + "id": "T1548", + "name": "Abuse Elevation Control Mechanism", + "reference": "https://attack.mitre.org/techniques/T1548/", + "subtechnique": [ + { + "id": "T1548.002", + "name": "Bypass User Access Control", + "reference": "https://attack.mitre.org/techniques/T1548/002/" + } + ] } ] } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_mock_windir.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_mock_windir.json index 069dada4a099b..283278876929b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_mock_windir.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_mock_windir.json @@ -35,9 +35,16 @@ }, "technique": [ { - "id": "T1088", - "name": "Bypass User Account Control", - "reference": "https://attack.mitre.org/techniques/T1088/" + "id": "T1548", + "name": "Abuse Elevation Control Mechanism", + "reference": "https://attack.mitre.org/techniques/T1548/", + "subtechnique": [ + { + "id": "T1548.002", + "name": "Bypass User Access Control", + "reference": "https://attack.mitre.org/techniques/T1548/002/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_winfw_mmc_hijack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_winfw_mmc_hijack.json index 23d18b4ad17d7..3639072a5c70b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_winfw_mmc_hijack.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_winfw_mmc_hijack.json @@ -35,9 +35,16 @@ }, "technique": [ { - "id": "T1088", - "name": "Bypass User Account Control", - "reference": "https://attack.mitre.org/techniques/T1088/" + "id": "T1548", + "name": "Abuse Elevation Control Mechanism", + "reference": "https://attack.mitre.org/techniques/T1548/", + "subtechnique": [ + { + "id": "T1548.002", + "name": "Bypass User Access Control", + "reference": "https://attack.mitre.org/techniques/T1548/002/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json index a367f4c89a71c..5199c06d4ec76 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json @@ -36,9 +36,16 @@ }, "technique": [ { - "id": "T1093", - "name": "Process Hollowing", - "reference": "https://attack.mitre.org/techniques/T1093/" + "id": "T1055", + "name": "Process Injection", + "reference": "https://attack.mitre.org/techniques/T1055/", + "subtechnique": [ + { + "id": "T1055.012", + "name": "Process Hollowing", + "reference": "https://attack.mitre.org/techniques/T1055/012/" + } + ] } ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_svchost_childproc_childless.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_svchost_childproc_childless.json index 9ffd9eed711aa..7a8653946c1be 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_svchost_childproc_childless.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_svchost_childproc_childless.json @@ -35,9 +35,16 @@ }, "technique": [ { - "id": "T1093", - "name": "Process Hollowing", - "reference": "https://attack.mitre.org/techniques/T1093/" + "id": "T1055", + "name": "Process Injection", + "reference": "https://attack.mitre.org/techniques/T1055/", + "subtechnique": [ + { + "id": "T1055.012", + "name": "Process Hollowing", + "reference": "https://attack.mitre.org/techniques/T1055/012/" + } + ] } ] }, From c2a556bb70a36d633f6eeaad9da27058bf9d59a9 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Mon, 11 Jan 2021 10:15:19 -0800 Subject: [PATCH 05/64] [CI] Ensure checkout is cleaned up in packer cache script (#87762) Signed-off-by: Tyler Smalley Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .ci/packer_cache_for_branch.sh | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.ci/packer_cache_for_branch.sh b/.ci/packer_cache_for_branch.sh index bc427bf927f11..bbdf5484faf65 100755 --- a/.ci/packer_cache_for_branch.sh +++ b/.ci/packer_cache_for_branch.sh @@ -5,6 +5,17 @@ set -e branch="$1" checkoutDir="$(pwd)" +function cleanup() +{ + if [[ "$branch" != "master" ]]; then + rm --preserve-root -rf "$checkoutDir" + fi + + exit 0 +} + +trap 'cleanup' 0 + if [[ "$branch" != "master" ]]; then checkoutDir="/tmp/kibana-$branch" git clone https://github.com/elastic/kibana.git --branch "$branch" --depth 1 "$checkoutDir" @@ -56,6 +67,3 @@ echo "created $HOME/.kibana/bootstrap_cache/$branch.tar" .ci/build_docker.sh -if [[ "$branch" != "master" ]]; then - rm --preserve-root -rf "$checkoutDir" -fi From d4b3ea9c3d619a27801c34d84e429caf44243f8f Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Mon, 11 Jan 2021 13:27:32 -0500 Subject: [PATCH 06/64] Ensure we use the right duration for messaging on this alert (#87579) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../server/alerts/license_expiration_alert.test.ts | 10 ++++++---- .../server/alerts/license_expiration_alert.ts | 9 +++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.test.ts b/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.test.ts index c64b6e4b92984..e6ad484a8c8e4 100644 --- a/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.test.ts +++ b/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.test.ts @@ -17,11 +17,13 @@ jest.mock('../lib/alerts/fetch_clusters', () => ({ fetchClusters: jest.fn(), })); jest.mock('moment', () => { - return function () { + const moment = function () { return { format: () => 'THE_DATE', }; }; + moment.duration = () => ({ humanize: () => 'HUMANIZED_DURATION' }); + return moment; }); jest.mock('../static_globals', () => ({ @@ -170,11 +172,11 @@ describe('LicenseExpirationAlert', () => { action: '[Please update your license.](elasticsearch/nodes)', actionPlain: 'Please update your license.', internalFullMessage: - 'License expiration alert is firing for testCluster. Your license expires in THE_DATE. [Please update your license.](elasticsearch/nodes)', + 'License expiration alert is firing for testCluster. Your license expires in HUMANIZED_DURATION. [Please update your license.](elasticsearch/nodes)', internalShortMessage: - 'License expiration alert is firing for testCluster. Your license expires in THE_DATE. Please update your license.', + 'License expiration alert is firing for testCluster. Your license expires in HUMANIZED_DURATION. Please update your license.', clusterName, - expiredDate: 'THE_DATE', + expiredDate: 'HUMANIZED_DURATION', state: 'firing', }); }); diff --git a/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.ts b/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.ts index 9dacba1dfe0ec..f15b015ba84b8 100644 --- a/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.ts +++ b/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.ts @@ -17,11 +17,7 @@ import { LegacyAlert, } from '../../common/types/alerts'; import { AlertExecutorOptions, AlertInstance } from '../../../alerts/server'; -import { - ALERT_LICENSE_EXPIRATION, - FORMAT_DURATION_TEMPLATE_SHORT, - LEGACY_ALERT_DETAILS, -} from '../../common/constants'; +import { ALERT_LICENSE_EXPIRATION, LEGACY_ALERT_DETAILS } from '../../common/constants'; import { AlertMessageTokenType } from '../../common/enums'; import { AlertingDefaults } from './alert_helpers'; import { SanitizedAlert } from '../../../alerts/common'; @@ -113,12 +109,13 @@ export class LicenseExpirationAlert extends BaseAlert { ) { const legacyAlert = item.meta as LegacyAlert; const $expiry = moment(legacyAlert.metadata.time); + const $duration = moment.duration(+new Date() - $expiry.valueOf()); if (alertState.ui.isFiring) { const actionText = i18n.translate('xpack.monitoring.alerts.licenseExpiration.action', { defaultMessage: 'Please update your license.', }); const action = `[${actionText}](elasticsearch/nodes)`; - const expiredDate = $expiry.format(FORMAT_DURATION_TEMPLATE_SHORT).trim(); + const expiredDate = $duration.humanize(); instance.scheduleActions('default', { internalShortMessage: i18n.translate( 'xpack.monitoring.alerts.licenseExpiration.firing.internalShortMessage', From f384c484b7039025299df0dfe0ce8a32361e51c6 Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Mon, 11 Jan 2021 18:32:24 +0000 Subject: [PATCH 07/64] [Task Manager] adds additional polling stats to Task Manager monitoring (#87766) Adds additional polling stats to Task Manager monitoring: - **duration**: Running average of polling duration measuring the time from the scheduled polling cycle start until all claimed tasks are marked as running - **claim_conflicts**: Running average of number of version clashes caused by the markAvailableTasksAsClaimed stage of the polling cycle - **claim_mismatches**: Running average of mismatch between the number of tasks updated by the markAvailableTasksAsClaimed stage of the polling cycle and the number of docs found by the sweepForClaimedTasks stage - **load** - Running average of the percentage of workers in use at the end of each polling cycle. --- .../plugins/task_manager/server/MONITORING.md | 59 ++++++++-- .../task_manager/server/lib/fill_pool.test.ts | 75 +++++++++---- .../task_manager/server/lib/fill_pool.ts | 48 +++++--- .../monitoring/task_run_statistics.test.ts | 38 +++++-- .../server/monitoring/task_run_statistics.ts | 104 ++++++++++++++---- .../server/polling_lifecycle.test.ts | 14 ++- .../task_manager/server/polling_lifecycle.ts | 50 ++++++--- .../task_manager/server/routes/health.test.ts | 4 + .../task_manager/server/task_events.ts | 40 ++++++- .../plugins/task_manager/server/task_pool.ts | 23 +++- .../server/task_running/task_runner.ts | 4 - .../task_manager/server/task_scheduling.ts | 12 +- .../plugins/task_manager/server/task_store.ts | 31 +++--- .../test_suites/task_manager/health_route.ts | 14 ++- 14 files changed, 384 insertions(+), 132 deletions(-) diff --git a/x-pack/plugins/task_manager/server/MONITORING.md b/x-pack/plugins/task_manager/server/MONITORING.md index 3595b86317489..64481e81c60a4 100644 --- a/x-pack/plugins/task_manager/server/MONITORING.md +++ b/x-pack/plugins/task_manager/server/MONITORING.md @@ -78,9 +78,10 @@ These are "Cold" stat which are updated at a regular cadence, configured by the #### The Runtime Section The `runtime` tracks Task Manager's performance as it runs, making note of task execution time, _drift_ etc. These include: - - The time it takes a task to run (mean and median, using a configurable running average window, `50` by default) - - The average _drift_ that tasks experience (mean and median, using the same configurable running average window as above). Drift tells us how long after a task's scheduled a task typically executes. - - The polling rate (the timestamp of the last time a polling cycle completed) and the result [`No tasks | Filled task pool | Unexpectedly ran out of workers`] frequency the past 50 polling cycles (using the same window size as the one used for running averages) + - The time it takes a task to run (p50, p90, p95 & p99, using a configurable running average window, `50` by default) + - The average _drift_ that tasks experience (p50, p90, p95 & p99, using the same configurable running average window as above). Drift tells us how long after a task's scheduled a task typically executes. + - The average _load_ (p50, p90, p95 & p99, using the same configurable running average window as above). Load tells us what percentage of workers is in use at the end of each polling cycle. + - The polling rate (the timestamp of the last time a polling cycle completed), the polling health stats (number of version clashes and mismatches) and the result [`No tasks | Filled task pool | Unexpectedly ran out of workers`] frequency the past 50 polling cycles (using the same window size as the one used for running averages) - The `Success | Retry | Failure ratio` by task type. This is different than the workload stats which tell you what's in the queue, but ca't keep track of retries and of non recurring tasks as they're wiped off the index when completed. These are "Hot" stats which are updated reactively as Tasks are executed and interacted with. @@ -174,10 +175,34 @@ For example, if you _curl_ the `/api/task_manager/_health` endpoint, you might g "status": "OK", "value": { "polling": { - /* When was the last polling cycle? */ + /* When was the last polling cycle? */ "last_successful_poll": "2020-10-05T17:57:55.411Z", - /* What is the frequency of polling cycle result? - Here we see 94% of "NoTasksClaimed" and 6% "PoolFilled" */ + /* Running average of polling duration measuring the time from the scheduled polling cycle + start until all claimed tasks are marked as running */ + "duration": { + "p50": 4, + "p90": 12, + "p95": 12, + "p99": 12 + }, + /* Running average of number of version clashes caused by the markAvailableTasksAsClaimed stage + of the polling cycle */ + "claim_conflicts": { + "p50": 0, + "p90": 0, + "p95": 0, + "p99": 0 + }, + /* Running average of mismatch between the number of tasks updated by the markAvailableTasksAsClaimed stage + of the polling cycle and the number of docs found by the sweepForClaimedTasks stage */ + "claim_mismatches": { + "p50": 0, + "p90": 0, + "p95": 0, + "p99": 0 + }, + /* What is the frequency of polling cycle result? + Here we see 94% of "NoTasksClaimed" and 6% "PoolFilled" */ "result_frequency_percent_as_number": { /* This tells us that the polling cycle didnt claim any new tasks */ "NoTasksClaimed": 94, @@ -196,14 +221,25 @@ For example, if you _curl_ the `/api/task_manager/_health` endpoint, you might g "Failed": 0 } }, - /* on average, the tasks in this deployment run 1.7s after their scheduled time */ + /* on average, 50% of the tasks in this deployment run at most 1.7s after their scheduled time */ "drift": { - "mean": 1720, - "median": 2276 + "p50": 1720, + "p90": 2274, + "p95": 2574, + "p99": 3221 + }, + /* on average, 50% of the tasks polling cycles in this deployment result at most in 25% of workers being in use. + We track this in percentages rather than absolute count as max_workers can change over time in response + to changing circumstance. */ + "load": { + "p50": 25, + "p90": 80, + "p95": 100, + "p99": 100 }, "execution": { "duration": { - /* on average, the `endpoint:user-artifact-packager` tasks take 15ms to run */ + /* on average, the `endpoint:user-artifact-packager` tasks take 15ms to run */ "endpoint:user-artifact-packager": { "mean": 15, "median": 14.5 @@ -230,7 +266,8 @@ For example, if you _curl_ the `/api/task_manager/_health` endpoint, you might g } }, "result_frequency_percent_as_number": { - /* and 100% of `endpoint:user-artifact-packager` have completed in success (within the running average window, so the past 50 runs (by default, configrable by `monitored_stats_running_average_window`) */ + /* and 100% of `endpoint:user-artifact-packager` have completed in success (within the running average window, + so the past 50 runs (by default, configrable by `monitored_stats_running_average_window`) */ "endpoint:user-artifact-packager": { "status": "OK", "Success": 100, diff --git a/x-pack/plugins/task_manager/server/lib/fill_pool.test.ts b/x-pack/plugins/task_manager/server/lib/fill_pool.test.ts index a2c1eb514aebc..effdee78b6504 100644 --- a/x-pack/plugins/task_manager/server/lib/fill_pool.test.ts +++ b/x-pack/plugins/task_manager/server/lib/fill_pool.test.ts @@ -6,24 +6,62 @@ import _ from 'lodash'; import sinon from 'sinon'; -import { fillPool } from './fill_pool'; +import { fillPool, FillPoolResult } from './fill_pool'; import { TaskPoolRunResult } from '../task_pool'; -import { asOk } from './result_type'; +import { asOk, Result } from './result_type'; +import { ClaimOwnershipResult } from '../task_store'; +import { ConcreteTaskInstance, TaskStatus } from '../task'; +import { TaskManagerRunner } from '../task_running/task_runner'; + +jest.mock('../task_running/task_runner'); describe('fillPool', () => { + function mockFetchAvailableTasks( + tasksToMock: number[][] + ): () => Promise> { + const tasks: ConcreteTaskInstance[][] = tasksToMock.map((ids) => mockTaskInstances(ids)); + let index = 0; + return async () => + asOk({ + stats: { + tasksUpdated: tasks[index + 1]?.length ?? 0, + tasksConflicted: 0, + tasksClaimed: 0, + }, + docs: tasks[index++] || [], + }); + } + + const mockTaskInstances = (ids: number[]): ConcreteTaskInstance[] => + ids.map((id) => ({ + id: `${id}`, + attempts: 0, + status: TaskStatus.Running, + version: '123', + runAt: new Date(0), + scheduledAt: new Date(0), + startedAt: new Date(0), + retryAt: new Date(0), + state: { + startedAt: new Date(0), + }, + taskType: '', + params: {}, + ownerId: null, + })); + test('stops filling when pool runs all claimed tasks, even if there is more capacity', async () => { const tasks = [ [1, 2, 3], [4, 5], ]; - let index = 0; - const fetchAvailableTasks = async () => asOk(tasks[index++] || []); + const fetchAvailableTasks = mockFetchAvailableTasks(tasks); const run = sinon.spy(async () => TaskPoolRunResult.RunningAllClaimedTasks); const converter = _.identity; await fillPool(fetchAvailableTasks, converter, run); - expect(_.flattenDeep(run.args)).toEqual([1, 2, 3]); + expect(_.flattenDeep(run.args)).toEqual(mockTaskInstances([1, 2, 3])); }); test('stops filling when the pool has no more capacity', async () => { @@ -31,14 +69,13 @@ describe('fillPool', () => { [1, 2, 3], [4, 5], ]; - let index = 0; - const fetchAvailableTasks = async () => asOk(tasks[index++] || []); + const fetchAvailableTasks = mockFetchAvailableTasks(tasks); const run = sinon.spy(async () => TaskPoolRunResult.RanOutOfCapacity); const converter = _.identity; await fillPool(fetchAvailableTasks, converter, run); - expect(_.flattenDeep(run.args)).toEqual([1, 2, 3]); + expect(_.flattenDeep(run.args)).toEqual(mockTaskInstances([1, 2, 3])); }); test('calls the converter on the records prior to running', async () => { @@ -46,10 +83,10 @@ describe('fillPool', () => { [1, 2, 3], [4, 5], ]; - let index = 0; - const fetchAvailableTasks = async () => asOk(tasks[index++] || []); + const fetchAvailableTasks = mockFetchAvailableTasks(tasks); const run = sinon.spy(async () => TaskPoolRunResult.RanOutOfCapacity); - const converter = (x: number) => x.toString(); + const converter = (instance: ConcreteTaskInstance) => + (instance.id as unknown) as TaskManagerRunner; await fillPool(fetchAvailableTasks, converter, run); @@ -59,7 +96,8 @@ describe('fillPool', () => { describe('error handling', () => { test('throws exception from fetchAvailableTasks', async () => { const run = sinon.spy(async () => TaskPoolRunResult.RanOutOfCapacity); - const converter = (x: number) => x.toString(); + const converter = (instance: ConcreteTaskInstance) => + (instance.id as unknown) as TaskManagerRunner; try { const fetchAvailableTasks = async () => Promise.reject('fetch is not working'); @@ -73,15 +111,15 @@ describe('fillPool', () => { test('throws exception from run', async () => { const run = sinon.spy(() => Promise.reject('run is not working')); - const converter = (x: number) => x.toString(); + const converter = (instance: ConcreteTaskInstance) => + (instance.id as unknown) as TaskManagerRunner; try { const tasks = [ [1, 2, 3], [4, 5], ]; - let index = 0; - const fetchAvailableTasks = async () => asOk(tasks[index++] || []); + const fetchAvailableTasks = mockFetchAvailableTasks(tasks); await fillPool(fetchAvailableTasks, converter, run); } catch (err) { @@ -95,11 +133,10 @@ describe('fillPool', () => { [1, 2, 3], [4, 5], ]; - let index = 0; - const fetchAvailableTasks = async () => asOk(tasks[index++] || []); + const fetchAvailableTasks = mockFetchAvailableTasks(tasks); const run = sinon.spy(async () => TaskPoolRunResult.RanOutOfCapacity); - const converter = (x: number) => { - throw new Error(`can not convert ${x}`); + const converter = (instance: ConcreteTaskInstance) => { + throw new Error(`can not convert ${instance.id}`); }; await fillPool(fetchAvailableTasks, converter, run); diff --git a/x-pack/plugins/task_manager/server/lib/fill_pool.ts b/x-pack/plugins/task_manager/server/lib/fill_pool.ts index 5ab173755662f..c58c074e2255b 100644 --- a/x-pack/plugins/task_manager/server/lib/fill_pool.ts +++ b/x-pack/plugins/task_manager/server/lib/fill_pool.ts @@ -5,7 +5,11 @@ */ import { performance } from 'perf_hooks'; +import { ConcreteTaskInstance } from '../task'; +import { WithTaskTiming, startTaskTimer } from '../task_events'; import { TaskPoolRunResult } from '../task_pool'; +import { TaskManagerRunner } from '../task_running'; +import { ClaimOwnershipResult } from '../task_store'; import { Result, map } from './result_type'; export enum FillPoolResult { @@ -17,9 +21,10 @@ export enum FillPoolResult { PoolFilled = 'PoolFilled', } -type BatchRun = (tasks: T[]) => Promise; -type Fetcher = () => Promise>; -type Converter = (t: T1) => T2; +export type ClaimAndFillPoolResult = Partial> & { + result: FillPoolResult; +}; +export type TimedFillPoolResult = WithTaskTiming; /** * Given a function that runs a batch of tasks (e.g. taskPool.run), a function @@ -33,26 +38,35 @@ type Converter = (t: T1) => T2; * @param fetchAvailableTasks - a function that fetches task records (e.g. store.fetchAvailableTasks) * @param converter - a function that converts task records to the appropriate task runner */ -export async function fillPool( - fetchAvailableTasks: Fetcher, - converter: Converter, - run: BatchRun -): Promise { +export async function fillPool( + fetchAvailableTasks: () => Promise>, + converter: (taskInstance: ConcreteTaskInstance) => TaskManagerRunner, + run: (tasks: TaskManagerRunner[]) => Promise +): Promise { performance.mark('fillPool.start'); - return map>( + const stopTaskTimer = startTaskTimer(); + const augmentTimingTo = ( + result: FillPoolResult, + stats?: ClaimOwnershipResult['stats'] + ): TimedFillPoolResult => ({ + result, + stats, + timing: stopTaskTimer(), + }); + return map>( await fetchAvailableTasks(), - async (instances) => { - if (!instances.length) { + async ({ docs, stats }) => { + if (!docs.length) { performance.mark('fillPool.bailNoTasks'); performance.measure( 'fillPool.activityDurationUntilNoTasks', 'fillPool.start', 'fillPool.bailNoTasks' ); - return FillPoolResult.NoTasksClaimed; + return augmentTimingTo(FillPoolResult.NoTasksClaimed, stats); } - const tasks = instances.map(converter); + const tasks = docs.map(converter); switch (await run(tasks)) { case TaskPoolRunResult.RanOutOfCapacity: @@ -62,15 +76,15 @@ export async function fillPool( 'fillPool.start', 'fillPool.bailExhaustedCapacity' ); - return FillPoolResult.RanOutOfCapacity; + return augmentTimingTo(FillPoolResult.RanOutOfCapacity, stats); case TaskPoolRunResult.RunningAtCapacity: performance.mark('fillPool.cycle'); - return FillPoolResult.RunningAtCapacity; + return augmentTimingTo(FillPoolResult.RunningAtCapacity, stats); default: performance.mark('fillPool.cycle'); - return FillPoolResult.PoolFilled; + return augmentTimingTo(FillPoolResult.PoolFilled, stats); } }, - async (result) => result + async (result) => augmentTimingTo(result) ); } diff --git a/x-pack/plugins/task_manager/server/monitoring/task_run_statistics.test.ts b/x-pack/plugins/task_manager/server/monitoring/task_run_statistics.test.ts index 7d5a8811dbe2b..21ea72cbbb00d 100644 --- a/x-pack/plugins/task_manager/server/monitoring/task_run_statistics.test.ts +++ b/x-pack/plugins/task_manager/server/monitoring/task_run_statistics.test.ts @@ -523,16 +523,34 @@ describe('Task Run Statistics', () => { } }); - events$.next(asTaskPollingCycleEvent(asOk(FillPoolResult.NoTasksClaimed))); - events$.next(asTaskPollingCycleEvent(asOk(FillPoolResult.NoTasksClaimed))); - events$.next(asTaskPollingCycleEvent(asOk(FillPoolResult.NoTasksClaimed))); - events$.next(asTaskPollingCycleEvent(asOk(FillPoolResult.PoolFilled))); - events$.next(asTaskPollingCycleEvent(asOk(FillPoolResult.PoolFilled))); - events$.next(asTaskPollingCycleEvent(asOk(FillPoolResult.PoolFilled))); - events$.next(asTaskPollingCycleEvent(asOk(FillPoolResult.RanOutOfCapacity))); - events$.next(asTaskPollingCycleEvent(asOk(FillPoolResult.RanOutOfCapacity))); - events$.next(asTaskPollingCycleEvent(asOk(FillPoolResult.NoTasksClaimed))); - events$.next(asTaskPollingCycleEvent(asOk(FillPoolResult.NoTasksClaimed))); + const timing = { + start: 0, + stop: 0, + }; + events$.next( + asTaskPollingCycleEvent(asOk({ result: FillPoolResult.NoTasksClaimed, timing })) + ); + events$.next( + asTaskPollingCycleEvent(asOk({ result: FillPoolResult.NoTasksClaimed, timing })) + ); + events$.next( + asTaskPollingCycleEvent(asOk({ result: FillPoolResult.NoTasksClaimed, timing })) + ); + events$.next(asTaskPollingCycleEvent(asOk({ result: FillPoolResult.PoolFilled, timing }))); + events$.next(asTaskPollingCycleEvent(asOk({ result: FillPoolResult.PoolFilled, timing }))); + events$.next(asTaskPollingCycleEvent(asOk({ result: FillPoolResult.PoolFilled, timing }))); + events$.next( + asTaskPollingCycleEvent(asOk({ result: FillPoolResult.RanOutOfCapacity, timing })) + ); + events$.next( + asTaskPollingCycleEvent(asOk({ result: FillPoolResult.RanOutOfCapacity, timing })) + ); + events$.next( + asTaskPollingCycleEvent(asOk({ result: FillPoolResult.NoTasksClaimed, timing })) + ); + events$.next( + asTaskPollingCycleEvent(asOk({ result: FillPoolResult.NoTasksClaimed, timing })) + ); }); }); }); diff --git a/x-pack/plugins/task_manager/server/monitoring/task_run_statistics.ts b/x-pack/plugins/task_manager/server/monitoring/task_run_statistics.ts index c1851789a769d..3933443296c4a 100644 --- a/x-pack/plugins/task_manager/server/monitoring/task_run_statistics.ts +++ b/x-pack/plugins/task_manager/server/monitoring/task_run_statistics.ts @@ -7,7 +7,7 @@ import { combineLatest, Observable } from 'rxjs'; import { filter, startWith, map } from 'rxjs/operators'; import { JsonObject } from 'src/plugins/kibana_utils/common'; -import { mapValues } from 'lodash'; +import { isNumber, mapValues } from 'lodash'; import { AggregatedStatProvider, AggregatedStat } from './runtime_statistics_aggregator'; import { TaskLifecycleEvent } from '../polling_lifecycle'; import { @@ -17,11 +17,12 @@ import { ErroredTask, RanTask, TaskTiming, + isTaskManagerStatEvent, } from '../task_events'; import { isOk, Ok, unwrap } from '../lib/result_type'; import { ConcreteTaskInstance } from '../task'; import { TaskRunResult } from '../task_running'; -import { FillPoolResult } from '../lib/fill_pool'; +import { FillPoolResult, ClaimAndFillPoolResult } from '../lib/fill_pool'; import { AveragedStat, calculateRunningAverage, @@ -35,6 +36,9 @@ import { TaskExecutionFailureThreshold, TaskManagerConfig } from '../config'; interface FillPoolStat extends JsonObject { last_successful_poll: string; + duration: number[]; + claim_conflicts: number[]; + claim_mismatches: number[]; result_frequency_percent_as_number: FillPoolResult[]; } @@ -45,6 +49,7 @@ interface ExecutionStat extends JsonObject { export interface TaskRunStat extends JsonObject { drift: number[]; + load: number[]; execution: ExecutionStat; polling: FillPoolStat | Omit; } @@ -74,6 +79,7 @@ type ResultFrequencySummary = ResultFrequency & { export interface SummarizedTaskRunStat extends JsonObject { drift: AveragedStat; + load: AveragedStat; execution: { duration: Record; result_frequency_percent_as_number: Record; @@ -86,7 +92,9 @@ export function createTaskRunAggregator( runningAverageWindowSize: number ): AggregatedStatProvider { const taskRunEventToStat = createTaskRunEventToStat(runningAverageWindowSize); - const taskRunEvents$: Observable> = taskPollingLifecycle.events.pipe( + const taskRunEvents$: Observable< + Pick + > = taskPollingLifecycle.events.pipe( filter((taskEvent: TaskLifecycleEvent) => isTaskRunEvent(taskEvent) && hasTiming(taskEvent)), map((taskEvent: TaskLifecycleEvent) => { const { task, result }: RanTask | ErroredTask = unwrap((taskEvent as TaskRun).event); @@ -94,21 +102,55 @@ export function createTaskRunAggregator( }) ); + const loadQueue = createRunningAveragedStat(runningAverageWindowSize); + const taskManagerLoadStatEvents$: Observable< + Pick + > = taskPollingLifecycle.events.pipe( + filter( + (taskEvent: TaskLifecycleEvent) => + isTaskManagerStatEvent(taskEvent) && + taskEvent.id === 'load' && + isOk(taskEvent.event) + ), + map((taskEvent: TaskLifecycleEvent) => { + return { + load: loadQueue(((taskEvent.event as unknown) as Ok).value), + }; + }) + ); + const resultFrequencyQueue = createRunningAveragedStat(runningAverageWindowSize); + const pollingDurationQueue = createRunningAveragedStat(runningAverageWindowSize); + const claimConflictsQueue = createRunningAveragedStat(runningAverageWindowSize); + const claimMismatchesQueue = createRunningAveragedStat(runningAverageWindowSize); const taskPollingEvents$: Observable< Pick > = taskPollingLifecycle.events.pipe( filter( (taskEvent: TaskLifecycleEvent) => - isTaskPollingCycleEvent(taskEvent) && isOk(taskEvent.event) + isTaskPollingCycleEvent(taskEvent) && isOk(taskEvent.event) ), map((taskEvent: TaskLifecycleEvent) => { + const { + result, + stats: { tasksClaimed, tasksUpdated, tasksConflicted } = {}, + } = ((taskEvent.event as unknown) as Ok).value; + const duration = (taskEvent?.timing?.stop ?? 0) - (taskEvent?.timing?.start ?? 0); return { polling: { last_successful_poll: new Date().toISOString(), - result_frequency_percent_as_number: resultFrequencyQueue( - ((taskEvent.event as unknown) as Ok).value - ), + // Track how long the polling cycle took from begining until all claimed tasks were marked as running + duration: duration ? pollingDurationQueue(duration) : pollingDurationQueue(), + // Track how many version conflicts occured during polling + claim_conflicts: isNumber(tasksConflicted) + ? claimConflictsQueue(tasksConflicted) + : claimConflictsQueue(), + // Track how much of a mismatch there is between claimed and updated + claim_mismatches: + isNumber(tasksClaimed) && isNumber(tasksUpdated) + ? claimMismatchesQueue(tasksUpdated - tasksClaimed) + : claimMismatchesQueue(), + result_frequency_percent_as_number: resultFrequencyQueue(result), }, }; }) @@ -118,21 +160,34 @@ export function createTaskRunAggregator( taskRunEvents$.pipe( startWith({ drift: [], execution: { duration: {}, result_frequency_percent_as_number: {} } }) ), + taskManagerLoadStatEvents$.pipe(startWith({ load: [] })), taskPollingEvents$.pipe( startWith({ - polling: { result_frequency_percent_as_number: [] }, + polling: { + duration: [], + claim_conflicts: [], + claim_mismatches: [], + result_frequency_percent_as_number: [], + }, }) ), ]).pipe( - map(([taskRun, polling]: [Omit, Pick]) => { - return { - key: 'runtime', - value: { - ...taskRun, - ...polling, - }, - } as AggregatedStat; - }) + map( + ([taskRun, load, polling]: [ + Pick, + Pick, + Pick + ]) => { + return { + key: 'runtime', + value: { + ...taskRun, + ...load, + ...polling, + }, + } as AggregatedStat; + } + ) ); } @@ -176,9 +231,16 @@ const DEFAULT_POLLING_FREQUENCIES = { export function summarizeTaskRunStat( { - // eslint-disable-next-line @typescript-eslint/naming-convention - polling: { last_successful_poll, result_frequency_percent_as_number: pollingResultFrequency }, + polling: { + // eslint-disable-next-line @typescript-eslint/naming-convention + last_successful_poll, + duration: pollingDuration, + result_frequency_percent_as_number: pollingResultFrequency, + claim_conflicts: claimConflicts, + claim_mismatches: claimMismatches, + }, drift, + load, execution: { duration, result_frequency_percent_as_number: executionResultFrequency }, }: TaskRunStat, config: TaskManagerConfig @@ -187,12 +249,16 @@ export function summarizeTaskRunStat( value: { polling: { ...(last_successful_poll ? { last_successful_poll } : {}), + duration: calculateRunningAverage(pollingDuration as number[]), + claim_conflicts: calculateRunningAverage(claimConflicts as number[]), + claim_mismatches: calculateRunningAverage(claimMismatches as number[]), result_frequency_percent_as_number: { ...DEFAULT_POLLING_FREQUENCIES, ...calculateFrequency(pollingResultFrequency as FillPoolResult[]), }, }, drift: calculateRunningAverage(drift), + load: calculateRunningAverage(load), execution: { duration: mapValues(duration, (typedDurations) => calculateRunningAverage(typedDurations)), result_frequency_percent_as_number: mapValues( diff --git a/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts b/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts index 0f807976970cf..bf3ff6da9fbdc 100644 --- a/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts +++ b/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts @@ -120,7 +120,12 @@ describe('TaskPollingLifecycle', () => { describe('claimAvailableTasks', () => { test('should claim Available Tasks when there are available workers', () => { const logger = mockLogger(); - const claim = jest.fn(() => Promise.resolve({ docs: [], claimedTasks: 0 })); + const claim = jest.fn(() => + Promise.resolve({ + docs: [], + stats: { tasksUpdated: 0, tasksConflicted: 0, tasksClaimed: 0 }, + }) + ); const availableWorkers = 1; @@ -131,7 +136,12 @@ describe('TaskPollingLifecycle', () => { test('should not claim Available Tasks when there are no available workers', () => { const logger = mockLogger(); - const claim = jest.fn(() => Promise.resolve({ docs: [], claimedTasks: 0 })); + const claim = jest.fn(() => + Promise.resolve({ + docs: [], + stats: { tasksUpdated: 0, tasksConflicted: 0, tasksClaimed: 0 }, + }) + ); const availableWorkers = 0; diff --git a/x-pack/plugins/task_manager/server/polling_lifecycle.ts b/x-pack/plugins/task_manager/server/polling_lifecycle.ts index 1876c52b0029e..a4522f350f745 100644 --- a/x-pack/plugins/task_manager/server/polling_lifecycle.ts +++ b/x-pack/plugins/task_manager/server/polling_lifecycle.ts @@ -12,7 +12,7 @@ import { Option, some, map as mapOptional } from 'fp-ts/lib/Option'; import { tap } from 'rxjs/operators'; import { Logger } from '../../../../src/core/server'; -import { Result, asErr, mapErr, asOk } from './lib/result_type'; +import { Result, asErr, mapErr, asOk, map } from './lib/result_type'; import { ManagedConfiguration } from './lib/create_managed_configuration'; import { TaskManagerConfig } from './config'; @@ -24,8 +24,9 @@ import { asTaskRunRequestEvent, TaskPollingCycle, asTaskPollingCycleEvent, + TaskManagerStat, } from './task_events'; -import { fillPool, FillPoolResult } from './lib/fill_pool'; +import { fillPool, FillPoolResult, TimedFillPoolResult } from './lib/fill_pool'; import { Middleware } from './lib/middleware'; import { intervalFromNow } from './lib/intervals'; import { ConcreteTaskInstance } from './task'; @@ -56,7 +57,8 @@ export type TaskLifecycleEvent = | TaskRun | TaskClaim | TaskRunRequest - | TaskPollingCycle; + | TaskPollingCycle + | TaskManagerStat; /** * The public interface into the task manager system. @@ -99,8 +101,9 @@ export class TaskPollingLifecycle { this.definitions = definitions; this.store = taskStore; + const emitEvent = (event: TaskLifecycleEvent) => this.events$.next(event); // pipe store events into the lifecycle event stream - this.store.events.subscribe((event) => this.events$.next(event)); + this.store.events.subscribe(emitEvent); this.bufferedStore = new BufferedTaskStore(this.store, { bufferMaxOperations: config.max_workers, @@ -111,6 +114,7 @@ export class TaskPollingLifecycle { logger, maxWorkers$: maxWorkersConfiguration$, }); + this.pool.load.subscribe(emitEvent); const { max_poll_inactivity_cycles: maxPollInactivityCycles, @@ -119,10 +123,10 @@ export class TaskPollingLifecycle { // the task poller that polls for work on fixed intervals and on demand const poller$: Observable< - Result> - > = createObservableMonitor>, Error>( + Result> + > = createObservableMonitor>, Error>( () => - createTaskPoller({ + createTaskPoller({ logger, pollInterval$: pollIntervalConfiguration$, bufferCapacity: config.request_capacity, @@ -189,7 +193,7 @@ export class TaskPollingLifecycle { return !this.pollingSubscription.closed; } - private pollForWork = async (...tasksToClaim: string[]): Promise => { + private pollForWork = async (...tasksToClaim: string[]): Promise => { return fillPool( // claim available tasks () => @@ -206,7 +210,9 @@ export class TaskPollingLifecycle { ); }; - private subscribeToPoller(poller$: Observable>>) { + private subscribeToPoller( + poller$: Observable>> + ) { return poller$ .pipe( tap( @@ -221,8 +227,14 @@ export class TaskPollingLifecycle { }) ) ) - .subscribe((event: Result>) => { - this.emitEvent(asTaskPollingCycleEvent(event)); + .subscribe((result: Result>) => { + this.emitEvent( + map( + result, + ({ timing, ...event }) => asTaskPollingCycleEvent(asOk(event), timing), + (event) => asTaskPollingCycleEvent(asErr(event)) + ) + ); }); } } @@ -232,18 +244,22 @@ export async function claimAvailableTasks( claim: (opts: OwnershipClaimingOpts) => Promise, availableWorkers: number, logger: Logger -): Promise> { +): Promise> { if (availableWorkers > 0) { performance.mark('claimAvailableTasks_start'); try { - const { docs, claimedTasks } = await claim({ + const claimResult = await claim({ size: availableWorkers, claimOwnershipUntil: intervalFromNow('30s')!, claimTasksById, }); + const { + docs, + stats: { tasksClaimed }, + } = claimResult; - if (claimedTasks === 0) { + if (tasksClaimed === 0) { performance.mark('claimAvailableTasks.noTasks'); } performance.mark('claimAvailableTasks_stop'); @@ -253,14 +269,14 @@ export async function claimAvailableTasks( 'claimAvailableTasks_stop' ); - if (docs.length !== claimedTasks) { + if (docs.length !== tasksClaimed) { logger.warn( - `[Task Ownership error]: ${claimedTasks} tasks were claimed by Kibana, but ${ + `[Task Ownership error]: ${tasksClaimed} tasks were claimed by Kibana, but ${ docs.length } task(s) were fetched (${docs.map((doc) => doc.id).join(', ')})` ); } - return asOk(docs); + return asOk(claimResult); } catch (ex) { if (identifyEsError(ex).includes('cannot execute [inline] scripts')) { logger.warn( diff --git a/x-pack/plugins/task_manager/server/routes/health.test.ts b/x-pack/plugins/task_manager/server/routes/health.test.ts index 5a0cef8eda94b..e0b34a3d1df12 100644 --- a/x-pack/plugins/task_manager/server/routes/health.test.ts +++ b/x-pack/plugins/task_manager/server/routes/health.test.ts @@ -356,12 +356,16 @@ function mockHealthStats(overrides = {}) { timestamp: new Date().toISOString(), value: { drift: [1000, 60000], + load: [0, 100, 75], execution: { duration: [], result_frequency_percent_as_number: [], }, polling: { last_successful_poll: new Date().toISOString(), + duration: [500, 400, 3000], + claim_conflicts: [0, 100, 75], + claim_mismatches: [0, 100, 75], result_frequency_percent_as_number: [ 'NoTasksClaimed', 'NoTasksClaimed', diff --git a/x-pack/plugins/task_manager/server/task_events.ts b/x-pack/plugins/task_manager/server/task_events.ts index 0b2ae3023deb6..fc09738a149a2 100644 --- a/x-pack/plugins/task_manager/server/task_events.ts +++ b/x-pack/plugins/task_manager/server/task_events.ts @@ -9,7 +9,7 @@ import { Option } from 'fp-ts/lib/Option'; import { ConcreteTaskInstance } from './task'; import { Result, Err } from './lib/result_type'; -import { FillPoolResult } from './lib/fill_pool'; +import { ClaimAndFillPoolResult } from './lib/fill_pool'; import { PollingError } from './polling'; import { TaskRunResult } from './task_running'; @@ -19,23 +19,25 @@ export enum TaskEventType { TASK_RUN = 'TASK_RUN', TASK_RUN_REQUEST = 'TASK_RUN_REQUEST', TASK_POLLING_CYCLE = 'TASK_POLLING_CYCLE', + TASK_MANAGER_STAT = 'TASK_MANAGER_STAT', } export interface TaskTiming { start: number; stop: number; } +export type WithTaskTiming = T & { timing: TaskTiming }; export function startTaskTimer(): () => TaskTiming { const start = Date.now(); return () => ({ start, stop: Date.now() }); } -export interface TaskEvent { - id?: string; +export interface TaskEvent { + id?: ID; timing?: TaskTiming; type: TaskEventType; - event: Result; + event: Result; } export interface RanTask { task: ConcreteTaskInstance; @@ -49,7 +51,17 @@ export type TaskMarkRunning = TaskEvent; export type TaskRun = TaskEvent; export type TaskClaim = TaskEvent>; export type TaskRunRequest = TaskEvent; -export type TaskPollingCycle = TaskEvent>; +export type TaskPollingCycle = TaskEvent>; + +export type TaskManagerStats = 'load'; +export type TaskManagerStat = TaskEvent; + +export type OkResultOf = EventType extends TaskEvent + ? OkResult + : never; +export type ErrResultOf = EventType extends TaskEvent + ? ErrorResult + : never; export function asTaskMarkRunningEvent( id: string, @@ -105,7 +117,7 @@ export function asTaskRunRequestEvent( } export function asTaskPollingCycleEvent( - event: Result>, + event: Result>, timing?: TaskTiming ): TaskPollingCycle { return { @@ -115,6 +127,17 @@ export function asTaskPollingCycleEvent( }; } +export function asTaskManagerStatEvent( + id: TaskManagerStats, + event: Result +): TaskManagerStat { + return { + id, + type: TaskEventType.TASK_MANAGER_STAT, + event, + }; +} + export function isTaskMarkRunningEvent( taskEvent: TaskEvent ): taskEvent is TaskMarkRunning { @@ -136,3 +159,8 @@ export function isTaskPollingCycleEvent( ): taskEvent is TaskPollingCycle { return taskEvent.type === TaskEventType.TASK_POLLING_CYCLE; } +export function isTaskManagerStatEvent( + taskEvent: TaskEvent +): taskEvent is TaskManagerStat { + return taskEvent.type === TaskEventType.TASK_MANAGER_STAT; +} diff --git a/x-pack/plugins/task_manager/server/task_pool.ts b/x-pack/plugins/task_manager/server/task_pool.ts index 6946cd613e0a7..561a222310f3e 100644 --- a/x-pack/plugins/task_manager/server/task_pool.ts +++ b/x-pack/plugins/task_manager/server/task_pool.ts @@ -8,13 +8,15 @@ * This module contains the logic that ensures we don't run too many * tasks at once in a given Kibana instance. */ -import { Observable } from 'rxjs'; +import { Observable, Subject } from 'rxjs'; import moment, { Duration } from 'moment'; import { performance } from 'perf_hooks'; import { padStart } from 'lodash'; import { Logger } from '../../../../src/core/server'; import { TaskRunner } from './task_running'; import { isTaskSavedObjectNotFoundError } from './lib/is_task_not_found_error'; +import { TaskManagerStat, asTaskManagerStatEvent } from './task_events'; +import { asOk } from './lib/result_type'; interface Opts { maxWorkers$: Observable; @@ -39,6 +41,7 @@ export class TaskPool { private maxWorkers: number = 0; private running = new Set(); private logger: Logger; + private load$ = new Subject(); /** * Creates an instance of TaskPool. @@ -56,6 +59,10 @@ export class TaskPool { }); } + public get load(): Observable { + return this.load$; + } + /** * Gets how many workers are currently in use. */ @@ -64,17 +71,21 @@ export class TaskPool { } /** - * Gets how many workers are currently available. + * Gets % of workers in use */ - public get availableWorkers() { - return this.maxWorkers - this.occupiedWorkers; + public get workerLoad() { + return this.maxWorkers ? Math.round((this.occupiedWorkers * 100) / this.maxWorkers) : 100; } /** * Gets how many workers are currently available. */ - public get hasAvailableWorkers() { - return this.availableWorkers > 0; + public get availableWorkers() { + // emit load whenever we check how many available workers there are + // this should happen less often than the actual changes to the worker queue + // so is lighter than emitting the load every time we add/remove a task from the queue + this.load$.next(asTaskManagerStatEvent('load', asOk(this.workerLoad))); + return this.maxWorkers - this.occupiedWorkers; } /** diff --git a/x-pack/plugins/task_manager/server/task_running/task_runner.ts b/x-pack/plugins/task_manager/server/task_running/task_runner.ts index 23d21d205ec26..d281a65da332c 100644 --- a/x-pack/plugins/task_manager/server/task_running/task_runner.ts +++ b/x-pack/plugins/task_manager/server/task_running/task_runner.ts @@ -76,10 +76,6 @@ export enum TaskRunResult { Success = 'Success', // Recurring Task completed successfully SuccessRescheduled = 'Success', - // // Task completed successfully after a retry - // SuccessfulRetry = 'SuccessfulRetry', - // // Recurring Task completed successfully after a retry - // SuccessfulRetryRescheduled = 'SuccessfulRetry', // Task has failed and a retry has been scheduled RetryScheduled = 'RetryScheduled', // Task has failed diff --git a/x-pack/plugins/task_manager/server/task_scheduling.ts b/x-pack/plugins/task_manager/server/task_scheduling.ts index 9806ada386e4a..bb4812ae6fce7 100644 --- a/x-pack/plugins/task_manager/server/task_scheduling.ts +++ b/x-pack/plugins/task_manager/server/task_scheduling.ts @@ -16,6 +16,8 @@ import { isTaskRunRequestEvent, RanTask, ErroredTask, + OkResultOf, + ErrResultOf, } from './task_events'; import { Middleware } from './lib/middleware'; import { @@ -29,7 +31,6 @@ import { import { TaskStore } from './task_store'; import { ensureDeprecatedFieldsAreCorrected } from './lib/correct_deprecated_fields'; import { TaskLifecycleEvent, TaskPollingLifecycle } from './polling_lifecycle'; -import { FillPoolResult } from './lib/fill_pool'; const VERSION_CONFLICT_STATUS = 409; @@ -125,19 +126,16 @@ export class TaskScheduling { return reject(await this.identifyTaskFailureReason(taskId, error)); }, taskEvent.event); } else { - either< - RanTask | ConcreteTaskInstance | FillPoolResult, - Error | ErroredTask | Option - >( + either, ErrResultOf>( taskEvent.event, - (taskInstance: RanTask | ConcreteTaskInstance | FillPoolResult) => { + (taskInstance: OkResultOf) => { // resolve if the task has run sucessfully if (isTaskRunEvent(taskEvent)) { subscription.unsubscribe(); resolve({ id: (taskInstance as RanTask).task.id }); } }, - async (errorResult: Error | ErroredTask | Option) => { + async (errorResult: ErrResultOf) => { // reject if any error event takes place for the requested task subscription.unsubscribe(); return reject( diff --git a/x-pack/plugins/task_manager/server/task_store.ts b/x-pack/plugins/task_manager/server/task_store.ts index 0d5d2431e227f..5d17c6246088a 100644 --- a/x-pack/plugins/task_manager/server/task_store.ts +++ b/x-pack/plugins/task_manager/server/task_store.ts @@ -98,7 +98,11 @@ export interface FetchResult { } export interface ClaimOwnershipResult { - claimedTasks: number; + stats: { + tasksUpdated: number; + tasksConflicted: number; + tasksClaimed: number; + }; docs: ConcreteTaskInstance[]; } @@ -214,16 +218,13 @@ export class TaskStore { this.serializer.generateRawId(undefined, 'task', id) ); - const numberOfTasksClaimed = await this.markAvailableTasksAsClaimed( - claimOwnershipUntil, - claimTasksByIdWithRawIds, - size - ); + const { + updated: tasksUpdated, + version_conflicts: tasksConflicted, + } = await this.markAvailableTasksAsClaimed(claimOwnershipUntil, claimTasksByIdWithRawIds, size); const docs = - numberOfTasksClaimed > 0 - ? await this.sweepForClaimedTasks(claimTasksByIdWithRawIds, size) - : []; + tasksUpdated > 0 ? await this.sweepForClaimedTasks(claimTasksByIdWithRawIds, size) : []; const [documentsReturnedById, documentsClaimedBySchedule] = partition(docs, (doc) => claimTasksById.includes(doc.id) @@ -250,7 +251,11 @@ export class TaskStore { ]); return { - claimedTasks: documentsClaimedById.length + documentsClaimedBySchedule.length, + stats: { + tasksUpdated, + tasksConflicted, + tasksClaimed: documentsClaimedById.length + documentsClaimedBySchedule.length, + }, docs: docs.filter((doc) => doc.status === TaskStatus.Claiming), }; }; @@ -259,7 +264,7 @@ export class TaskStore { claimOwnershipUntil: OwnershipClaimingOpts['claimOwnershipUntil'], claimTasksById: OwnershipClaimingOpts['claimTasksById'], size: OwnershipClaimingOpts['size'] - ): Promise { + ): Promise { const registeredTaskTypes = this.definitions.getAllTypes(); const taskMaxAttempts = [...this.definitions].reduce((accumulator, [type, { maxAttempts }]) => { return { ...accumulator, [type]: maxAttempts || this.maxAttempts }; @@ -282,7 +287,7 @@ export class TaskStore { } const apmTrans = apm.startTransaction(`taskManager markAvailableTasksAsClaimed`, 'taskManager'); - const { updated } = await this.updateByQuery( + const result = await this.updateByQuery( asUpdateByQuery({ query: matchesClauses( mustBeAllOf( @@ -309,7 +314,7 @@ export class TaskStore { ); if (apmTrans) apmTrans.end(); - return updated; + return result; } /** diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/health_route.ts b/x-pack/test/plugin_api_integration/test_suites/task_manager/health_route.ts index eb8e35fd871f3..4c84ca1298e10 100644 --- a/x-pack/test/plugin_api_integration/test_suites/task_manager/health_route.ts +++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/health_route.ts @@ -33,12 +33,14 @@ interface MonitoringStats { timestamp: string; value: { drift: Record; + load: Record; execution: { duration: Record>; result_frequency_percent_as_number: Record>; }; polling: { last_successful_poll: string; + duration: Record; result_frequency_percent_as_number: Record; }; }; @@ -170,7 +172,7 @@ export default function ({ getService }: FtrProviderContext) { const { runtime: { - value: { drift, polling, execution }, + value: { drift, load, polling, execution }, }, } = (await getHealth()).stats; @@ -182,11 +184,21 @@ export default function ({ getService }: FtrProviderContext) { expect(typeof polling.result_frequency_percent_as_number.RunningAtCapacity).to.eql('number'); expect(typeof polling.result_frequency_percent_as_number.Failed).to.eql('number'); + expect(typeof polling.duration.p50).to.eql('number'); + expect(typeof polling.duration.p90).to.eql('number'); + expect(typeof polling.duration.p95).to.eql('number'); + expect(typeof polling.duration.p99).to.eql('number'); + expect(typeof drift.p50).to.eql('number'); expect(typeof drift.p90).to.eql('number'); expect(typeof drift.p95).to.eql('number'); expect(typeof drift.p99).to.eql('number'); + expect(typeof load.p50).to.eql('number'); + expect(typeof load.p90).to.eql('number'); + expect(typeof load.p95).to.eql('number'); + expect(typeof load.p99).to.eql('number'); + expect(typeof execution.duration.sampleTask.p50).to.eql('number'); expect(typeof execution.duration.sampleTask.p90).to.eql('number'); expect(typeof execution.duration.sampleTask.p95).to.eql('number'); From 379f9c9646d46243c65d943e3593ca2f7104877e Mon Sep 17 00:00:00 2001 From: Kevin Logan <56395104+kevinlog@users.noreply.github.com> Date: Mon, 11 Jan 2021 13:55:15 -0500 Subject: [PATCH 08/64] [Security Solution] ensure that license is preserved when loading policy details (#87780) --- .../management/pages/policy/store/policy_details/reducer.ts | 5 +++-- .../pages/policy/store/policy_details/selectors.ts | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer.ts index a6e94d3715ca3..e875690f0e1cf 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { fullPolicy, isOnPolicyDetailsPage } from './selectors'; +import { fullPolicy, isOnPolicyDetailsPage, license } from './selectors'; import { Immutable, PolicyConfig, @@ -45,7 +45,6 @@ export const initialPolicyDetailsState: () => Immutable = () total: 0, other: 0, }, - license: undefined, }); export const policyDetailsReducer: ImmutableReducer = ( @@ -108,6 +107,7 @@ export const policyDetailsReducer: ImmutableReducer) => { ); }; +/** Returns the license info fetched from the license service */ +export const license = (state: Immutable) => { + return state.license; +}; + /** Returns the policyId from the url */ export const policyIdFromParams: (state: Immutable) => string = createSelector( (state) => state.location, From 2658855cb7c66432d5a98455e740112fd86f311e Mon Sep 17 00:00:00 2001 From: Frank Hassanabad Date: Mon, 11 Jan 2021 12:15:02 -0700 Subject: [PATCH 09/64] Adds workaround for hapi h2o2 proxy issue for DELETE REST calls that have bodies in developer mode (#87270) ## Summary When you run Kibana in developer mode you have 3 random digits assigned to your URL and we proxy things through a [h2o2 proxy](https://github.com/hapijs/h2o2) to help the developers with development with regards to proxies ```ts node --max-old-space-size=2048 scripts/kibana --dev ``` However when you try to send a body with the DELETE verb in the browser such as using the `security_solution` and try to delete a rule: Screen Shot 2021-01-04 at 8 06 15 PM You get an error toaster showing up who's content is "Bad Request": Screen Shot 2021-01-04 at 8 03 14 PM The reason for this bug looks to be from our proxy usage of `h2o2` when we are in development mode where it removes `content-length` when you send a body with a `DELETE`. I created a bug and workaround for the `h2o2` project directly: https://github.com/hapijs/h2o2/issues/124 This fix here is the workaround applied to Kibana. With this workaround applied there should be no more error toasters for developers. Additional fixes/improvements are: * I ported the unit tests from `src/core/server/http/http_server.test.ts` to `src/core/server/http/base_path_proxy_server.test.ts` since the `base_path_proxy_server` did not have any unit tests. I also added additional unit tests to cover the specific use cases that are in `base_path_proxy_server` * I fixed the placement of some tests from `src/core/server/http/http_server.test.ts` where there were a few that were under the wrong describe block and I changed a few `it` -> `test` as it looks like that file should be consistent with `test` instead of odd mixture of `it`. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../http/base_path_proxy_server.test.ts | 1052 +++++++++++++++++ .../server/http/base_path_proxy_server.ts | 21 +- src/core/server/http/http_server.test.ts | 125 +- 3 files changed, 1130 insertions(+), 68 deletions(-) create mode 100644 src/core/server/http/base_path_proxy_server.test.ts diff --git a/src/core/server/http/base_path_proxy_server.test.ts b/src/core/server/http/base_path_proxy_server.test.ts new file mode 100644 index 0000000000000..9f4ffdcf8e081 --- /dev/null +++ b/src/core/server/http/base_path_proxy_server.test.ts @@ -0,0 +1,1052 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { BasePathProxyServer, BasePathProxyServerOptions } from './base_path_proxy_server'; +import { loggingSystemMock } from '../logging/logging_system.mock'; +import { DevConfig } from '../dev/dev_config'; +import { EMPTY } from 'rxjs'; +import { HttpConfig } from './http_config'; +import { ByteSizeValue, schema } from '@kbn/config-schema'; +import { + KibanaRequest, + KibanaResponseFactory, + Router, + RouteValidationFunction, + RouteValidationResultFactory, +} from './router'; +import { HttpServer } from './http_server'; +import supertest from 'supertest'; +import { RequestHandlerContext } from 'kibana/server'; +import { readFileSync } from 'fs'; +import { KBN_CERT_PATH, KBN_KEY_PATH } from '@kbn/dev-utils'; +import { omit } from 'lodash'; +import { Readable } from 'stream'; + +/** + * Most of these tests are inspired by: + * src/core/server/http/http_server.test.ts + * and copied for completeness from that file. The modifications are that these tests use the developer proxy. + */ +describe('BasePathProxyServer', () => { + let server: HttpServer; + let proxyServer: BasePathProxyServer; + let config: HttpConfig; + let configWithSSL: HttpConfig; + let basePath: string; + let certificate: string; + let key: string; + let proxySupertest: supertest.SuperTest; + const logger = loggingSystemMock.createLogger(); + const enhanceWithContext = (fn: (...args: any[]) => any) => fn.bind(null, {}); + + beforeAll(() => { + certificate = readFileSync(KBN_CERT_PATH, 'utf8'); + key = readFileSync(KBN_KEY_PATH, 'utf8'); + }); + + beforeEach(async () => { + // setup the server but don't start it until each individual test so that routes can be dynamically configured per unit test. + server = new HttpServer(logger, 'tests'); + config = ({ + name: 'kibana', + host: '127.0.0.1', + port: 10012, + compression: { enabled: true }, + requestId: { + allowFromAnyIp: true, + ipAllowlist: [], + }, + autoListen: true, + keepaliveTimeout: 1000, + socketTimeout: 1000, + cors: { + enabled: false, + allowCredentials: false, + allowOrigin: [], + }, + ssl: { enabled: false }, + customResponseHeaders: {}, + maxPayload: new ByteSizeValue(1024), + rewriteBasePath: true, + } as unknown) as HttpConfig; + + configWithSSL = { + ...config, + ssl: { + enabled: true, + certificate, + cipherSuites: ['TLS_AES_256_GCM_SHA384'], + getSecureOptions: () => 0, + key, + redirectHttpFromPort: config.port + 1, + }, + } as HttpConfig; + + // setup and start the proxy server + const proxyConfig: HttpConfig = { ...config, port: 10013 }; + const devConfig = new DevConfig({ basePathProxyTarget: config.port }); + proxyServer = new BasePathProxyServer(logger, proxyConfig, devConfig); + const options: Readonly = { + shouldRedirectFromOldBasePath: () => true, + delayUntil: () => EMPTY, + }; + await proxyServer.start(options); + + // set the base path or throw if for some unknown reason it is not setup + if (proxyServer.basePath == null) { + throw new Error('Invalid null base path, all tests will fail'); + } else { + basePath = proxyServer.basePath; + } + proxySupertest = supertest(`http://127.0.0.1:${proxyConfig.port}`); + }); + + afterEach(async () => { + await server.stop(); + await proxyServer.stop(); + jest.clearAllMocks(); + }); + + test('root URL will return a 302 redirect', async () => { + await proxySupertest.get('/').expect(302); + }); + + test('root URL will return a redirect location with exactly 3 characters that are a-z', async () => { + const res = await proxySupertest.get('/'); + const location = res.header.location; + expect(location).toMatch(/[a-z]{3}/); + }); + + test('valid params', async () => { + const router = new Router(`${basePath}/foo`, logger, enhanceWithContext); + router.get( + { + path: '/{test}', + validate: { + params: schema.object({ + test: schema.string(), + }), + }, + }, + (_, req, res) => { + return res.ok({ body: req.params.test }); + } + ); + const { registerRouter } = await server.setup(config); + registerRouter(router); + await server.start(); + + await proxySupertest + .get(`${basePath}/foo/some-string`) + .expect(200) + .then((res) => { + expect(res.text).toBe('some-string'); + }); + }); + + test('invalid params', async () => { + const router = new Router(`${basePath}/foo`, logger, enhanceWithContext); + + router.get( + { + path: '/{test}', + validate: { + params: schema.object({ + test: schema.number(), + }), + }, + }, + (_, req, res) => { + return res.ok({ body: String(req.params.test) }); + } + ); + + const { registerRouter } = await server.setup(config); + registerRouter(router); + + await server.start(); + + await proxySupertest + .get(`${basePath}/foo/some-string`) + .expect(400) + .then((res) => { + expect(res.body).toEqual({ + error: 'Bad Request', + statusCode: 400, + message: '[request params.test]: expected value of type [number] but got [string]', + }); + }); + }); + + test('valid query', async () => { + const router = new Router(`${basePath}/foo`, logger, enhanceWithContext); + + router.get( + { + path: '/', + validate: { + query: schema.object({ + bar: schema.string(), + quux: schema.number(), + }), + }, + }, + (_, req, res) => { + return res.ok({ body: req.query }); + } + ); + + const { registerRouter } = await server.setup(config); + registerRouter(router); + + await server.start(); + + await proxySupertest + .get(`${basePath}/foo/?bar=test&quux=123`) + .expect(200) + .then((res) => { + expect(res.body).toEqual({ bar: 'test', quux: 123 }); + }); + }); + + test('invalid query', async () => { + const router = new Router(`${basePath}/foo`, logger, enhanceWithContext); + + router.get( + { + path: '/', + validate: { + query: schema.object({ + bar: schema.number(), + }), + }, + }, + (_, req, res) => { + return res.ok({ body: req.query }); + } + ); + + const { registerRouter } = await server.setup(config); + registerRouter(router); + + await server.start(); + + await proxySupertest + .get(`${basePath}/foo/?bar=test`) + .expect(400) + .then((res) => { + expect(res.body).toEqual({ + error: 'Bad Request', + statusCode: 400, + message: '[request query.bar]: expected value of type [number] but got [string]', + }); + }); + }); + + test('valid body', async () => { + const router = new Router(`${basePath}/foo`, logger, enhanceWithContext); + + router.post( + { + path: '/', + validate: { + body: schema.object({ + bar: schema.string(), + baz: schema.number(), + }), + }, + }, + (_, req, res) => { + return res.ok({ body: req.body }); + } + ); + + const { registerRouter } = await server.setup(config); + registerRouter(router); + + await server.start(); + + await proxySupertest + .post(`${basePath}/foo/`) + .send({ + bar: 'test', + baz: 123, + }) + .expect(200) + .then((res) => { + expect(res.body).toEqual({ bar: 'test', baz: 123 }); + }); + }); + + test('valid body with validate function', async () => { + const router = new Router(`${basePath}/foo`, logger, enhanceWithContext); + + router.post( + { + path: '/', + validate: { + body: ({ bar, baz } = {}, { ok, badRequest }) => { + if (typeof bar === 'string' && typeof baz === 'number') { + return ok({ bar, baz }); + } else { + return badRequest('Wrong payload', ['body']); + } + }, + }, + }, + (_, req, res) => { + return res.ok({ body: req.body }); + } + ); + + const { registerRouter } = await server.setup(config); + registerRouter(router); + + await server.start(); + + await proxySupertest + .post(`${basePath}/foo/`) + .send({ + bar: 'test', + baz: 123, + }) + .expect(200) + .then((res) => { + expect(res.body).toEqual({ bar: 'test', baz: 123 }); + }); + }); + + test('not inline validation - specifying params', async () => { + const router = new Router(`${basePath}/foo`, logger, enhanceWithContext); + + const bodyValidation = ( + { bar, baz }: any = {}, + { ok, badRequest }: RouteValidationResultFactory + ) => { + if (typeof bar === 'string' && typeof baz === 'number') { + return ok({ bar, baz }); + } else { + return badRequest('Wrong payload', ['body']); + } + }; + + router.post( + { + path: '/', + validate: { + body: bodyValidation, + }, + }, + (_, req, res) => { + return res.ok({ body: req.body }); + } + ); + + const { registerRouter } = await server.setup(config); + registerRouter(router); + + await server.start(); + + await proxySupertest + .post(`${basePath}/foo/`) + .send({ + bar: 'test', + baz: 123, + }) + .expect(200) + .then((res) => { + expect(res.body).toEqual({ bar: 'test', baz: 123 }); + }); + }); + + test('not inline validation - specifying validation handler', async () => { + const router = new Router(`${basePath}/foo`, logger, enhanceWithContext); + + const bodyValidation: RouteValidationFunction<{ bar: string; baz: number }> = ( + { bar, baz } = {}, + { ok, badRequest } + ) => { + if (typeof bar === 'string' && typeof baz === 'number') { + return ok({ bar, baz }); + } else { + return badRequest('Wrong payload', ['body']); + } + }; + + router.post( + { + path: '/', + validate: { + body: bodyValidation, + }, + }, + (_, req, res) => { + return res.ok({ body: req.body }); + } + ); + + const { registerRouter } = await server.setup(config); + registerRouter(router); + + await server.start(); + + await proxySupertest + .post(`${basePath}/foo/`) + .send({ + bar: 'test', + baz: 123, + }) + .expect(200) + .then((res) => { + expect(res.body).toEqual({ bar: 'test', baz: 123 }); + }); + }); + + test('not inline handler - KibanaRequest', async () => { + const router = new Router(`${basePath}/foo`, logger, enhanceWithContext); + + const handler = ( + context: RequestHandlerContext, + req: KibanaRequest, + res: KibanaResponseFactory + ) => { + const body = { + bar: req.body.bar.toUpperCase(), + baz: req.body.baz.toString(), + }; + + return res.ok({ body }); + }; + + router.post( + { + path: '/', + validate: { + body: ({ bar, baz } = {}, { ok, badRequest }) => { + if (typeof bar === 'string' && typeof baz === 'number') { + return ok({ bar, baz }); + } else { + return badRequest('Wrong payload', ['body']); + } + }, + }, + }, + handler + ); + + const { registerRouter } = await server.setup(config); + registerRouter(router); + + await server.start(); + + await proxySupertest + .post(`${basePath}/foo/`) + .send({ + bar: 'test', + baz: 123, + }) + .expect(200) + .then((res) => { + expect(res.body).toEqual({ bar: 'TEST', baz: '123' }); + }); + }); + + test('invalid body', async () => { + const router = new Router(`${basePath}/foo`, logger, enhanceWithContext); + + router.post( + { + path: '/', + validate: { + body: schema.object({ + bar: schema.number(), + }), + }, + }, + (_, req, res) => { + return res.ok({ body: req.body }); + } + ); + + const { registerRouter } = await server.setup(config); + registerRouter(router); + + await server.start(); + + await proxySupertest + .post(`${basePath}/foo/`) + .send({ bar: 'test' }) + .expect(400) + .then((res) => { + expect(res.body).toEqual({ + error: 'Bad Request', + statusCode: 400, + message: '[request body.bar]: expected value of type [number] but got [string]', + }); + }); + }); + + test('handles putting', async () => { + const router = new Router(`${basePath}/foo`, logger, enhanceWithContext); + + router.put( + { + path: '/', + validate: { + body: schema.object({ + key: schema.string(), + }), + }, + }, + (_, req, res) => { + return res.ok({ body: req.body }); + } + ); + + const { registerRouter } = await server.setup(config); + registerRouter(router); + + await server.start(); + + await proxySupertest + .put(`${basePath}/foo/`) + .send({ key: 'new value' }) + .expect(200) + .then((res) => { + expect(res.body).toEqual({ key: 'new value' }); + }); + }); + + test('handles deleting', async () => { + const router = new Router(`${basePath}/foo`, logger, enhanceWithContext); + + router.delete( + { + path: '/{id}', + validate: { + params: schema.object({ + id: schema.number(), + }), + }, + }, + (_, req, res) => { + return res.ok({ body: { key: req.params.id } }); + } + ); + + const { registerRouter } = await server.setup(config); + registerRouter(router); + + await server.start(); + + await proxySupertest + .delete(`${basePath}/foo/3`) + .expect(200) + .then((res) => { + expect(res.body).toEqual({ key: 3 }); + }); + }); + + describe('with `basepath: /bar` and `rewriteBasePath: false`', () => { + let configWithBasePath: HttpConfig; + + beforeEach(async () => { + configWithBasePath = { + ...config, + basePath: '/bar', + rewriteBasePath: false, + } as HttpConfig; + + const router = new Router(`${basePath}/`, logger, enhanceWithContext); + router.get({ path: '/', validate: false }, (_, __, res) => res.ok({ body: 'value:/' })); + router.get({ path: '/foo', validate: false }, (_, __, res) => res.ok({ body: 'value:/foo' })); + + const { registerRouter } = await server.setup(configWithBasePath); + registerRouter(router); + + await server.start(); + }); + + test('/bar => 404', async () => { + await proxySupertest.get(`${basePath}/bar`).expect(404); + }); + + test('/bar/ => 404', async () => { + await proxySupertest.get(`${basePath}/bar/`).expect(404); + }); + + test('/bar/foo => 404', async () => { + await proxySupertest.get(`${basePath}/bar/foo`).expect(404); + }); + + test('/ => /', async () => { + await proxySupertest + .get(`${basePath}/`) + .expect(200) + .then((res) => { + expect(res.text).toBe('value:/'); + }); + }); + + test('/foo => /foo', async () => { + await proxySupertest + .get(`${basePath}/foo`) + .expect(200) + .then((res) => { + expect(res.text).toBe('value:/foo'); + }); + }); + }); + + test('with defined `redirectHttpFromPort`', async () => { + const router = new Router(`${basePath}/`, logger, enhanceWithContext); + router.get({ path: '/', validate: false }, (_, __, res) => res.ok({ body: 'value:/' })); + + const { registerRouter } = await server.setup(configWithSSL); + registerRouter(router); + + await server.start(); + }); + + test('allows attaching metadata to attach meta-data tag strings to a route', async () => { + const tags = ['my:tag']; + const { registerRouter } = await server.setup(config); + + const router = new Router(basePath, logger, enhanceWithContext); + router.get({ path: '/with-tags', validate: false, options: { tags } }, (_, req, res) => + res.ok({ body: { tags: req.route.options.tags } }) + ); + router.get({ path: '/without-tags', validate: false }, (_, req, res) => + res.ok({ body: { tags: req.route.options.tags } }) + ); + registerRouter(router); + + await server.start(); + await proxySupertest.get(`${basePath}/with-tags`).expect(200, { tags }); + + await proxySupertest.get(`${basePath}/without-tags`).expect(200, { tags: [] }); + }); + + describe('response headers', () => { + test('default headers', async () => { + const { registerRouter } = await server.setup(config); + + const router = new Router(basePath, logger, enhanceWithContext); + router.get({ path: '/', validate: false }, (_, req, res) => res.ok({ body: req.route })); + registerRouter(router); + + await server.start(); + const response = await proxySupertest.get(`${basePath}/`).expect(200); + + const restHeaders = omit(response.header, ['date', 'content-length']); + expect(restHeaders).toMatchInlineSnapshot(` + Object { + "accept-ranges": "bytes", + "cache-control": "private, no-cache, no-store, must-revalidate", + "connection": "close", + "content-type": "application/json; charset=utf-8", + } + `); + }); + }); + + test('exposes route details of incoming request to a route handler (POST + payload options)', async () => { + const { registerRouter } = await server.setup(config); + + const router = new Router(basePath, logger, enhanceWithContext); + router.post( + { + path: '/', + validate: { body: schema.object({ test: schema.number() }) }, + options: { body: { accepts: 'application/json' } }, + }, + (_, req, res) => res.ok({ body: req.route }) + ); + registerRouter(router); + + await server.start(); + await proxySupertest + .post(`${basePath}/`) + .send({ test: 1 }) + .expect(200, { + method: 'post', + path: `${basePath}/`, + options: { + authRequired: true, + xsrfRequired: true, + tags: [], + timeout: { + payload: 10000, + idleSocket: 1000, + }, + body: { + parse: true, // hapi populates the default + maxBytes: 1024, // hapi populates the default + accepts: ['application/json'], + output: 'data', + }, + }, + }); + }); + + test('should return a stream in the body', async () => { + const { registerRouter } = await server.setup(config); + + const router = new Router(basePath, logger, enhanceWithContext); + router.put( + { + path: '/', + validate: { body: schema.stream() }, + options: { body: { output: 'stream' } }, + }, + (_, req, res) => { + try { + expect(req.body).toBeInstanceOf(Readable); + return res.ok({ body: req.route.options.body }); + } catch (err) { + return res.internalError({ body: err.message }); + } + } + ); + registerRouter(router); + + await server.start(); + await proxySupertest.put(`${basePath}/`).send({ test: 1 }).expect(200, { + parse: true, + maxBytes: 1024, // hapi populates the default + output: 'stream', + }); + }); + + describe('timeout options', () => { + describe('payload timeout', () => { + test('POST routes set the payload timeout', async () => { + const { registerRouter } = await server.setup(config); + + const router = new Router(basePath, logger, enhanceWithContext); + router.post( + { + path: '/', + validate: false, + options: { + timeout: { + payload: 300000, + }, + }, + }, + (_, req, res) => { + try { + return res.ok({ + body: { + timeout: req.route.options.timeout, + }, + }); + } catch (err) { + return res.internalError({ body: err.message }); + } + } + ); + registerRouter(router); + await server.start(); + await proxySupertest + .post(`${basePath}/`) + .send({ test: 1 }) + .expect(200, { + timeout: { + payload: 300000, + idleSocket: 1000, // This is an extra option added by the proxy + }, + }); + }); + + test('DELETE routes set the payload timeout', async () => { + const { registerRouter } = await server.setup(config); + + const router = new Router(basePath, logger, enhanceWithContext); + router.delete( + { + path: '/', + validate: false, + options: { + timeout: { + payload: 300000, + }, + }, + }, + (context, req, res) => { + try { + return res.ok({ + body: { + timeout: req.route.options.timeout, + }, + }); + } catch (err) { + return res.internalError({ body: err.message }); + } + } + ); + registerRouter(router); + await server.start(); + await proxySupertest.delete(`${basePath}/`).expect(200, { + timeout: { + payload: 300000, + idleSocket: 1000, // This is an extra option added by the proxy + }, + }); + }); + + test('PUT routes set the payload timeout and automatically adjusts the idle socket timeout', async () => { + const { registerRouter } = await server.setup(config); + + const router = new Router(basePath, logger, enhanceWithContext); + router.put( + { + path: '/', + validate: false, + options: { + timeout: { + payload: 300000, + }, + }, + }, + (_, req, res) => { + try { + return res.ok({ + body: { + timeout: req.route.options.timeout, + }, + }); + } catch (err) { + return res.internalError({ body: err.message }); + } + } + ); + registerRouter(router); + await server.start(); + await proxySupertest.put(`${basePath}/`).expect(200, { + timeout: { + payload: 300000, + idleSocket: 1000, // This is an extra option added by the proxy + }, + }); + }); + + test('PATCH routes set the payload timeout and automatically adjusts the idle socket timeout', async () => { + const { registerRouter } = await server.setup(config); + + const router = new Router(basePath, logger, enhanceWithContext); + router.patch( + { + path: '/', + validate: false, + options: { + timeout: { + payload: 300000, + }, + }, + }, + (_, req, res) => { + try { + return res.ok({ + body: { + timeout: req.route.options.timeout, + }, + }); + } catch (err) { + return res.internalError({ body: err.message }); + } + } + ); + registerRouter(router); + await server.start(); + await proxySupertest.patch(`${basePath}/`).expect(200, { + timeout: { + payload: 300000, + idleSocket: 1000, // This is an extra option added by the proxy + }, + }); + }); + }); + + describe('idleSocket timeout', () => { + test('uses server socket timeout when not specified in the route', async () => { + const { registerRouter } = await server.setup({ + ...config, + socketTimeout: 11000, + }); + + const router = new Router(basePath, logger, enhanceWithContext); + router.get( + { + path: '/', + validate: { body: schema.maybe(schema.any()) }, + }, + (_, req, res) => { + return res.ok({ + body: { + timeout: req.route.options.timeout, + }, + }); + } + ); + registerRouter(router); + + await server.start(); + await proxySupertest + .get(`${basePath}/`) + .send() + .expect(200, { + timeout: { + idleSocket: 11000, + }, + }); + }); + + test('sets the socket timeout when specified in the route', async () => { + const { registerRouter } = await server.setup({ + ...config, + socketTimeout: 11000, + }); + + const router = new Router(basePath, logger, enhanceWithContext); + router.get( + { + path: '/', + validate: { body: schema.maybe(schema.any()) }, + options: { timeout: { idleSocket: 12000 } }, + }, + (context, req, res) => { + return res.ok({ + body: { + timeout: req.route.options.timeout, + }, + }); + } + ); + registerRouter(router); + + await server.start(); + await proxySupertest + .get(`${basePath}/`) + .send() + .expect(200, { + timeout: { + idleSocket: 12000, + }, + }); + }); + + test('idleSocket timeout can be smaller than the payload timeout', async () => { + const { registerRouter } = await server.setup(config); + + const router = new Router(basePath, logger, enhanceWithContext); + router.post( + { + path: `${basePath}/`, + validate: { body: schema.any() }, + options: { + timeout: { + payload: 1000, + idleSocket: 10, + }, + }, + }, + (_, req, res) => { + return res.ok({ body: { timeout: req.route.options.timeout } }); + } + ); + + registerRouter(router); + + await server.start(); + }); + }); + }); + + describe('shouldRedirect', () => { + let proxyServerWithoutShouldRedirect: BasePathProxyServer; + let proxyWithoutShouldRedirectSupertest: supertest.SuperTest; + + beforeEach(async () => { + // setup and start a proxy server which does not use "shouldRedirectFromOldBasePath" + const proxyConfig: HttpConfig = { ...config, port: 10004 }; + const devConfig = new DevConfig({ basePathProxyTarget: config.port }); + proxyServerWithoutShouldRedirect = new BasePathProxyServer(logger, proxyConfig, devConfig); + const options: Readonly = { + shouldRedirectFromOldBasePath: () => false, // Return false to not redirect + delayUntil: () => EMPTY, + }; + await proxyServerWithoutShouldRedirect.start(options); + proxyWithoutShouldRedirectSupertest = supertest(`http://127.0.0.1:${proxyConfig.port}`); + }); + + afterEach(async () => { + await proxyServerWithoutShouldRedirect.stop(); + }); + + test('it will do a redirect if it detects what looks like a stale or previously used base path', async () => { + const fakeBasePath = basePath !== 'abc' ? 'abc' : 'efg'; + const res = await proxySupertest.get(`/${fakeBasePath}`).expect(302); + const location = res.header.location; + expect(location).toEqual(`${basePath}/`); + }); + + test('it will NOT do a redirect if it detects what looks like a stale or previously used base path if we intentionally turn it off', async () => { + const fakeBasePath = basePath !== 'abc' ? 'abc' : 'efg'; + await proxyWithoutShouldRedirectSupertest.get(`/${fakeBasePath}`).expect(404); + }); + + test('it will NOT redirect if it detects a larger path than 3 characters', async () => { + await proxySupertest.get('/abcde').expect(404); + }); + + test('it will NOT redirect if it is not a GET verb', async () => { + const fakeBasePath = basePath !== 'abc' ? 'abc' : 'efg'; + await proxySupertest.put(`/${fakeBasePath}`).expect(404); + }); + }); + + describe('constructor option for sending in a custom basePath', () => { + let proxyServerWithFooBasePath: BasePathProxyServer; + let proxyWithFooBasePath: supertest.SuperTest; + + beforeEach(async () => { + // setup and start a proxy server which uses a basePath of "foo" + const proxyConfig: HttpConfig = { ...config, port: 10004, basePath: '/foo' }; // <-- "foo" here in basePath + const devConfig = new DevConfig({ basePathProxyTarget: config.port }); + proxyServerWithFooBasePath = new BasePathProxyServer(logger, proxyConfig, devConfig); + const options: Readonly = { + shouldRedirectFromOldBasePath: () => true, + delayUntil: () => EMPTY, + }; + await proxyServerWithFooBasePath.start(options); + proxyWithFooBasePath = supertest(`http://127.0.0.1:${proxyConfig.port}`); + }); + + afterEach(async () => { + await proxyServerWithFooBasePath.stop(); + }); + + test('it will do a redirect to foo which is our passed in value for the configuration', async () => { + const res = await proxyWithFooBasePath.get('/bar').expect(302); + const location = res.header.location; + expect(location).toEqual('/foo/'); + }); + }); +}); diff --git a/src/core/server/http/base_path_proxy_server.ts b/src/core/server/http/base_path_proxy_server.ts index d461abe54ccbd..dfcd0757c2d1e 100644 --- a/src/core/server/http/base_path_proxy_server.ts +++ b/src/core/server/http/base_path_proxy_server.ts @@ -143,12 +143,25 @@ export class BasePathProxyServer { handler: { proxy: { agent: this.httpsAgent, - host: this.server.info.host, passThrough: true, - port: this.devConfig.basePathProxyTargetPort, - // typings mismatch. h2o2 doesn't support "socket" - protocol: this.server.info.protocol as HapiProxy.ProxyHandlerOptions['protocol'], xforward: true, + mapUri: async (request) => { + return { + // Passing in this header to merge it is a workaround until this is fixed: + // https://github.com/hapijs/h2o2/issues/124 + headers: + request.headers['content-length'] != null + ? { 'content-length': request.headers['content-length'] } + : undefined, + uri: Url.format({ + hostname: request.server.info.host, + port: this.devConfig.basePathProxyTargetPort, + protocol: request.server.info.protocol, + pathname: request.path, + query: request.query, + }), + }; + }, }, }, method: '*', diff --git a/src/core/server/http/http_server.test.ts b/src/core/server/http/http_server.test.ts index cbb60480c4cf1..70c346a5333cc 100644 --- a/src/core/server/http/http_server.test.ts +++ b/src/core/server/http/http_server.test.ts @@ -888,52 +888,48 @@ describe('conditional compression', () => { expect(response.header).not.toHaveProperty('content-encoding'); }); }); +}); - describe('response headers', () => { - it('allows to configure "keep-alive" header', async () => { - const { registerRouter, server: innerServer } = await server.setup({ - ...config, - keepaliveTimeout: 100_000, - }); +describe('response headers', () => { + test('allows to configure "keep-alive" header', async () => { + const { registerRouter, server: innerServer } = await server.setup({ + ...config, + keepaliveTimeout: 100_000, + }); - const router = new Router('', logger, enhanceWithContext); - router.get({ path: '/', validate: false }, (context, req, res) => - res.ok({ body: req.route }) - ); - registerRouter(router); + const router = new Router('', logger, enhanceWithContext); + router.get({ path: '/', validate: false }, (context, req, res) => res.ok({ body: req.route })); + registerRouter(router); - await server.start(); - const response = await supertest(innerServer.listener) - .get('/') - .set('Connection', 'keep-alive') - .expect(200); + await server.start(); + const response = await supertest(innerServer.listener) + .get('/') + .set('Connection', 'keep-alive') + .expect(200); - expect(response.header.connection).toBe('keep-alive'); - expect(response.header['keep-alive']).toBe('timeout=100'); - }); + expect(response.header.connection).toBe('keep-alive'); + expect(response.header['keep-alive']).toBe('timeout=100'); + }); - it('default headers', async () => { - const { registerRouter, server: innerServer } = await server.setup(config); + test('default headers', async () => { + const { registerRouter, server: innerServer } = await server.setup(config); - const router = new Router('', logger, enhanceWithContext); - router.get({ path: '/', validate: false }, (context, req, res) => - res.ok({ body: req.route }) - ); - registerRouter(router); + const router = new Router('', logger, enhanceWithContext); + router.get({ path: '/', validate: false }, (context, req, res) => res.ok({ body: req.route })); + registerRouter(router); - await server.start(); - const response = await supertest(innerServer.listener).get('/').expect(200); - - const restHeaders = omit(response.header, ['date', 'content-length']); - expect(restHeaders).toMatchInlineSnapshot(` - Object { - "accept-ranges": "bytes", - "cache-control": "private, no-cache, no-store, must-revalidate", - "connection": "close", - "content-type": "application/json; charset=utf-8", - } - `); - }); + await server.start(); + const response = await supertest(innerServer.listener).get('/').expect(200); + + const restHeaders = omit(response.header, ['date', 'content-length']); + expect(restHeaders).toMatchInlineSnapshot(` + Object { + "accept-ranges": "bytes", + "cache-control": "private, no-cache, no-store, must-revalidate", + "connection": "close", + "content-type": "application/json; charset=utf-8", + } + `); }); }); @@ -1270,31 +1266,31 @@ describe('timeout options', () => { }, }); }); - }); - test(`idleSocket timeout can be smaller than the payload timeout`, async () => { - const { registerRouter } = await server.setup(config); + test('idleSocket timeout can be smaller than the payload timeout', async () => { + const { registerRouter } = await server.setup(config); - const router = new Router('', logger, enhanceWithContext); - router.post( - { - path: '/', - validate: { body: schema.any() }, - options: { - timeout: { - payload: 1000, - idleSocket: 10, + const router = new Router('', logger, enhanceWithContext); + router.post( + { + path: '/', + validate: { body: schema.any() }, + options: { + timeout: { + payload: 1000, + idleSocket: 10, + }, }, }, - }, - (context, req, res) => { - return res.ok({ body: { timeout: req.route.options.timeout } }); - } - ); + (context, req, res) => { + return res.ok({ body: { timeout: req.route.options.timeout } }); + } + ); - registerRouter(router); + registerRouter(router); - await server.start(); + await server.start(); + }); }); }); @@ -1329,13 +1325,14 @@ test('should return a stream in the body', async () => { describe('setup contract', () => { describe('#createSessionStorage', () => { - it('creates session storage factory', async () => { + test('creates session storage factory', async () => { const { createCookieSessionStorageFactory } = await server.setup(config); const sessionStorageFactory = await createCookieSessionStorageFactory(cookieOptions); expect(sessionStorageFactory.asScoped).toBeDefined(); }); - it('creates session storage factory only once', async () => { + + test('creates session storage factory only once', async () => { const { createCookieSessionStorageFactory } = await server.setup(config); const create = async () => await createCookieSessionStorageFactory(cookieOptions); @@ -1343,7 +1340,7 @@ describe('setup contract', () => { expect(create()).rejects.toThrowError('A cookieSessionStorageFactory was already created'); }); - it('does not throw if called after stop', async () => { + test('does not throw if called after stop', async () => { const { createCookieSessionStorageFactory } = await server.setup(config); await server.stop(); expect(() => { @@ -1353,7 +1350,7 @@ describe('setup contract', () => { }); describe('#getServerInfo', () => { - it('returns correct information', async () => { + test('returns correct information', async () => { let { getServerInfo } = await server.setup(config); expect(getServerInfo()).toEqual({ @@ -1378,7 +1375,7 @@ describe('setup contract', () => { }); }); - it('returns correct protocol when ssl is enabled', async () => { + test('returns correct protocol when ssl is enabled', async () => { const { getServerInfo } = await server.setup(configWithSSL); expect(getServerInfo().protocol).toEqual('https'); @@ -1386,7 +1383,7 @@ describe('setup contract', () => { }); describe('#registerStaticDir', () => { - it('does not throw if called after stop', async () => { + test('does not throw if called after stop', async () => { const { registerStaticDir } = await server.setup(config); await server.stop(); expect(() => { From 89e7cd6808df0330962605415374564851d594cc Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Mon, 11 Jan 2021 12:28:24 -0700 Subject: [PATCH 10/64] [maps] abort sync data if any data request fails (#87381) * [maps] abort sync data if any data request fails * review feedback * fix broken rename of e to error Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../layers/vector_layer/vector_layer.tsx | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index f72d2c0e6ead9..0cb24be445c6e 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -384,14 +384,11 @@ export class VectorLayer extends AbstractLayer { join, propertiesMap, }; - } catch (e) { - if (!(e instanceof DataRequestAbortError)) { - onLoadError(sourceDataId, requestToken, `Join error: ${e.message}`); + } catch (error) { + if (!(error instanceof DataRequestAbortError)) { + onLoadError(sourceDataId, requestToken, `Join error: ${error.message}`); } - return { - dataHasChanged: true, - join, - }; + throw error; } } @@ -430,7 +427,7 @@ export class VectorLayer extends AbstractLayer { }; } - async _performInnerJoins( + _performInnerJoins( sourceResult: SourceResult, joinStates: JoinState[], updateSourceData: DataRequestContext['updateSourceData'] @@ -538,9 +535,7 @@ export class VectorLayer extends AbstractLayer { if (!(error instanceof DataRequestAbortError)) { onLoadError(dataRequestId, requestToken, error.message); } - return { - refreshed: false, - }; + throw error; } } @@ -646,6 +641,7 @@ export class VectorLayer extends AbstractLayer { if (!(error instanceof DataRequestAbortError)) { onLoadError(dataRequestId, requestToken, error.message); } + throw error; } } @@ -736,6 +732,7 @@ export class VectorLayer extends AbstractLayer { stopLoading(dataRequestId, requestToken, formatters, nextMeta); } catch (error) { onLoadError(dataRequestId, requestToken, error.message); + throw error; } } @@ -757,19 +754,26 @@ export class VectorLayer extends AbstractLayer { if (this.isLoadingBounds()) { return; } - await this._syncSourceStyleMeta(syncContext, source, style); - await this._syncSourceFormatters(syncContext, source, style); - const sourceResult = await this._syncSource(syncContext, source, style); - if ( - !sourceResult.featureCollection || - !sourceResult.featureCollection.features.length || - !this.hasJoins() - ) { - return; - } - const joinStates = await this._syncJoins(syncContext, style); - await this._performInnerJoins(sourceResult, joinStates, syncContext.updateSourceData); + try { + await this._syncSourceStyleMeta(syncContext, source, style); + await this._syncSourceFormatters(syncContext, source, style); + const sourceResult = await this._syncSource(syncContext, source, style); + if ( + !sourceResult.featureCollection || + !sourceResult.featureCollection.features.length || + !this.hasJoins() + ) { + return; + } + + const joinStates = await this._syncJoins(syncContext, style); + this._performInnerJoins(sourceResult, joinStates, syncContext.updateSourceData); + } catch (error) { + if (!(error instanceof DataRequestAbortError)) { + throw error; + } + } } _getSourceFeatureCollection() { From ff8d30bc6cc9e14e0ec1907eba271a93e66097a5 Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Mon, 11 Jan 2021 14:32:19 -0500 Subject: [PATCH 11/64] [Monitoring] Stop using constructor.name for logstash pipelines (#87386) * Use typeString instead * Used wrong type string Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../pipeline_viewer/models/pipeline/make_statement.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/models/pipeline/make_statement.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/models/pipeline/make_statement.js index 120230c0ffa16..b257182566f53 100644 --- a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/models/pipeline/make_statement.js +++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/models/pipeline/make_statement.js @@ -9,15 +9,14 @@ import { IfStatement } from './if_statement'; import { Queue } from './queue'; export function makeStatement(pipelineGraphVertex, pipelineStage) { - const klass = pipelineGraphVertex.constructor.name; - switch (klass) { - case 'PluginVertex': + switch (pipelineGraphVertex.typeString) { + case 'plugin': return PluginStatement.fromPipelineGraphVertex(pipelineGraphVertex, pipelineStage); - case 'IfVertex': + case 'if': return IfStatement.fromPipelineGraphVertex(pipelineGraphVertex, pipelineStage); - case 'QueueVertex': + case 'queue': return Queue.fromPipelineGraphVertex(pipelineGraphVertex, pipelineStage); default: - throw new Error(`Unknown vertex class: ${klass}`); + throw new Error(`Unknown vertex class: ${pipelineGraphVertex.typeString}`); } } From a9797999a1b85c2949770d4cb9e9f109c402965b Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Mon, 11 Jan 2021 11:39:04 -0800 Subject: [PATCH 12/64] [ML] Use documentation link service in more ML pages (#87389) --- .../__snapshots__/rule_editor_flyout.test.js.snap | 6 +++--- .../components/rule_editor/rule_editor_flyout.js | 3 +-- .../components/rule_editor/rule_editor_flyout.test.js | 7 +++++-- .../components/validate_job/validate_job_view.js | 3 +-- .../components/validate_job/validate_job_view.test.js | 7 +++++-- .../components/details_step/details_step_form.tsx | 8 ++------ .../edit_flyout/__snapshots__/overrides.test.js.snap | 2 +- .../file_based/components/edit_flyout/overrides.js | 3 +-- .../file_based/components/edit_flyout/overrides.test.js | 7 +++++-- .../calendars/list/__snapshots__/header.test.js.snap | 2 +- .../settings/calendars/list/calendars_list.test.js | 4 ---- .../public/application/settings/calendars/list/header.js | 4 +--- .../application/settings/calendars/list/header.test.js | 7 +++++-- .../application/settings/filter_lists/list/header.js | 3 +-- 14 files changed, 32 insertions(+), 34 deletions(-) diff --git a/x-pack/plugins/ml/public/application/components/rule_editor/__snapshots__/rule_editor_flyout.test.js.snap b/x-pack/plugins/ml/public/application/components/rule_editor/__snapshots__/rule_editor_flyout.test.js.snap index 6717e8fa5a51f..b4a424535c9e0 100644 --- a/x-pack/plugins/ml/public/application/components/rule_editor/__snapshots__/rule_editor_flyout.test.js.snap +++ b/x-pack/plugins/ml/public/application/components/rule_editor/__snapshots__/rule_editor_flyout.test.js.snap @@ -96,7 +96,7 @@ exports[`RuleEditorFlyout renders the flyout after adding a condition to a rule values={ Object { "learnMoreLink": ({ getDocLinks: () => ({ - ELASTIC_WEBSITE_URL: 'https://www.elastic.co/', - DOC_LINK_VERSION: 'jest-metadata-mock-branch', + links: { + ml: { + anomalyDetectionJobTips: 'jest-metadata-mock-url', + }, + }, }), })); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_form.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_form.tsx index b59fbe926aa4d..448dcd8b2e1ba 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_form.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_form.tsx @@ -43,8 +43,7 @@ export const DetailsStepForm: FC = ({ const { services: { docLinks, notifications }, } = useMlKibana(); - const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = docLinks; - + const createIndexLink = docLinks.links.apis.createIndex; const { setFormState } = actions; const { form, cloneJob, hasSwitchedToEditor, isJobCreated } = state; const { @@ -240,10 +239,7 @@ export const DetailsStepForm: FC = ({ } )}
- + {i18n.translate( 'xpack.ml.dataframe.stepDetailsForm.destinationIndexInvalidErrorLink', { diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/edit_flyout/__snapshots__/overrides.test.js.snap b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/edit_flyout/__snapshots__/overrides.test.js.snap index 24c9dc85979e7..6ab89fe3e4b2d 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/edit_flyout/__snapshots__/overrides.test.js.snap +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/edit_flyout/__snapshots__/overrides.test.js.snap @@ -84,7 +84,7 @@ exports[`Overrides render overrides 1`] = ` size="xs" > See more on accepted formats diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/edit_flyout/overrides.js b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/edit_flyout/overrides.js index bbbc33052f3c7..36d49bd37152e 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/edit_flyout/overrides.js +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/edit_flyout/overrides.js @@ -268,8 +268,7 @@ class OverridesUI extends Component { const fieldOptions = getSortedFields(fields); const timestampFormatErrorsList = [this.customTimestampFormatErrors, timestampFormatError]; - const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = this.props.kibana.services.docLinks; - const docsUrl = `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/search-aggregations-bucket-daterange-aggregation.html#date-format-pattern`; + const docsUrl = this.props.kibana.services.docLinks.links.aggs.date_format_pattern; const timestampFormatHelp = ( diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/edit_flyout/overrides.test.js b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/edit_flyout/overrides.test.js index 05ebf601b5979..4ad04cd248a18 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/edit_flyout/overrides.test.js +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/edit_flyout/overrides.test.js @@ -26,8 +26,11 @@ function getProps() { kibana: { services: { docLinks: { - ELASTIC_WEBSITE_URL: 'https://www.elastic.co/', - DOC_LINK_VERSION: 'jest-metadata-mock-branch', + links: { + aggs: { + date_format_pattern: 'jest-metadata-mock-url', + }, + }, }, }, }, diff --git a/x-pack/plugins/ml/public/application/settings/calendars/list/__snapshots__/header.test.js.snap b/x-pack/plugins/ml/public/application/settings/calendars/list/__snapshots__/header.test.js.snap index 2925b2c3d1c38..c19d8effb1b9a 100644 --- a/x-pack/plugins/ml/public/application/settings/calendars/list/__snapshots__/header.test.js.snap +++ b/x-pack/plugins/ml/public/application/settings/calendars/list/__snapshots__/header.test.js.snap @@ -90,7 +90,7 @@ exports[`CalendarListsHeader renders header 1`] = ` Object { "br":
, "learnMoreLink": {}, }, }, - docLinks: { - ELASTIC_WEBSITE_URL: 'https://www.elastic.co/', - DOC_LINK_VERSION: 'jest-metadata-mock-branch', - }, }, }, }; diff --git a/x-pack/plugins/ml/public/application/settings/calendars/list/header.js b/x-pack/plugins/ml/public/application/settings/calendars/list/header.js index bf4bc48b34720..62af8e5b6420b 100644 --- a/x-pack/plugins/ml/public/application/settings/calendars/list/header.js +++ b/x-pack/plugins/ml/public/application/settings/calendars/list/header.js @@ -26,9 +26,7 @@ import { import { withKibana } from '../../../../../../../../src/plugins/kibana_react/public'; function CalendarsListHeaderUI({ totalCount, refreshCalendars, kibana }) { - const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = kibana.services.docLinks; - - const docsUrl = `${ELASTIC_WEBSITE_URL}guide/en/machine-learning/${DOC_LINK_VERSION}/ml-calendars.html`; + const docsUrl = kibana.services.docLinks.links.ml.calendars; return ( diff --git a/x-pack/plugins/ml/public/application/settings/calendars/list/header.test.js b/x-pack/plugins/ml/public/application/settings/calendars/list/header.test.js index 3b674f3a71959..6600849b1c32c 100644 --- a/x-pack/plugins/ml/public/application/settings/calendars/list/header.test.js +++ b/x-pack/plugins/ml/public/application/settings/calendars/list/header.test.js @@ -24,8 +24,11 @@ describe('CalendarListsHeader', () => { kibana: { services: { docLinks: { - ELASTIC_WEBSITE_URL: 'https://www.elastic.co/', - DOC_LINK_VERSION: 'jest-metadata-mock-branch', + links: { + ml: { + calendars: 'jest-metadata-mock-url', + }, + }, }, }, }, diff --git a/x-pack/plugins/ml/public/application/settings/filter_lists/list/header.js b/x-pack/plugins/ml/public/application/settings/filter_lists/list/header.js index 1d300e3ae6301..bf8e5175568a0 100644 --- a/x-pack/plugins/ml/public/application/settings/filter_lists/list/header.js +++ b/x-pack/plugins/ml/public/application/settings/filter_lists/list/header.js @@ -26,8 +26,7 @@ import { import { withKibana } from '../../../../../../../../src/plugins/kibana_react/public'; function FilterListsHeaderUI({ totalCount, refreshFilterLists, kibana }) { - const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = kibana.services.docLinks; - const docsUrl = `${ELASTIC_WEBSITE_URL}guide/en/machine-learning/${DOC_LINK_VERSION}/ml-rules.html`; + const docsUrl = kibana.services.docLinks.links.ml.customRules; return ( From 1927556729427b2abceb5bc49f51eb1c04ba6bb2 Mon Sep 17 00:00:00 2001 From: Joe Portner <5295965+jportner@users.noreply.github.com> Date: Mon, 11 Jan 2021 14:52:54 -0500 Subject: [PATCH 13/64] Update reporting docs (#87651) --- docs/user/reporting/response-codes.asciidoc | 2 +- docs/user/reporting/script-example.asciidoc | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/user/reporting/response-codes.asciidoc b/docs/user/reporting/response-codes.asciidoc index 5ec9bf5300124..50a27766f37fb 100644 --- a/docs/user/reporting/response-codes.asciidoc +++ b/docs/user/reporting/response-codes.asciidoc @@ -9,7 +9,7 @@ the POST URL. This is true even if the job somehow fails later, since report generation happens asynchronously from queuing. - **`400` (Bad Request)**: When sending requests to the POST URL, if you don't use - `POST` as the HTTP method, or if your request is missing the `kbn-version` header, + `POST` as the HTTP method, or if your request is missing the `kbn-xsrf` header, Kibana will return a code `400` status response for the request. - **`503` (Service Unavailable)**: When using the `path` to request the download, you diff --git a/docs/user/reporting/script-example.asciidoc b/docs/user/reporting/script-example.asciidoc index 94301fc6fb448..56721d20ea3c7 100644 --- a/docs/user/reporting/script-example.asciidoc +++ b/docs/user/reporting/script-example.asciidoc @@ -3,7 +3,7 @@ The response from this request will be JSON, and will contain a `path` property URL to use to download the generated report. Use the `GET` method in the HTTP request to download the report. -The request method must be `POST` and it must include a `kbn-version` header for Kibana +The request method must be `POST` and it must include a `kbn-xsrf` header for Kibana to allow the request. The following example queues CSV report generation using the `POST` URL with cURL: @@ -13,7 +13,7 @@ The following example queues CSV report generation using the `POST` URL with cUR curl \ -XPOST \ <1> -u elastic \ <2> --H 'kbn-version: {version}' \ <3> +-H 'kbn-xsrf: true' \ <3> 'http://0.0.0.0:5601/api/reporting/generate/csv?jobParams=...' <4> --------------------------------------------------------- // CONSOLE @@ -21,8 +21,8 @@ curl \ <1> `POST` method is required. <2> Provide user credentials for a user with permission to access Kibana and {report-features}. -<3> The `kbn-version` header is required for all `POST` requests to Kibana. -**The value must match the dotted-numeral version of the Kibana instance.** +<3> The `kbn-xsrf` header is required for all `POST` requests to Kibana. For more information, see <>. <4> The POST URL. You can copy and paste the URL for any report from the Kibana UI. Here is an example response for a successfully queued report: From b10be9ec6f458669fe59ebc965a33ef663bdd97b Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 11 Jan 2021 21:00:00 +0100 Subject: [PATCH 14/64] [coverage] do not collect stats for mocha (#87859) --- .../code_coverage/shell_scripts/copy_mocha_reports.sh | 10 ---------- .../generate_team_assignments_and_ingest_coverage.sh | 6 ------ test/scripts/checks/mocha_coverage.sh | 5 ----- test/scripts/jenkins_unit.sh | 4 ---- vars/kibanaCoverage.groovy | 3 --- 5 files changed, 28 deletions(-) delete mode 100644 src/dev/code_coverage/shell_scripts/copy_mocha_reports.sh delete mode 100755 test/scripts/checks/mocha_coverage.sh diff --git a/src/dev/code_coverage/shell_scripts/copy_mocha_reports.sh b/src/dev/code_coverage/shell_scripts/copy_mocha_reports.sh deleted file mode 100644 index 579276aac990f..0000000000000 --- a/src/dev/code_coverage/shell_scripts/copy_mocha_reports.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -EXTRACT_START_DIR=tmp/extracted_coverage -EXTRACT_END_DIR=target/kibana-coverage -COMBINED_EXRACT_DIR=/${EXTRACT_START_DIR}/${EXTRACT_END_DIR} - - -echo "### Copy mocha reports" -mkdir -p $EXTRACT_END_DIR/mocha-combined -cp -r $COMBINED_EXRACT_DIR/mocha/. $EXTRACT_END_DIR/mocha-combined/ diff --git a/src/dev/code_coverage/shell_scripts/generate_team_assignments_and_ingest_coverage.sh b/src/dev/code_coverage/shell_scripts/generate_team_assignments_and_ingest_coverage.sh index 62b81929ae79b..caa1f1a761367 100644 --- a/src/dev/code_coverage/shell_scripts/generate_team_assignments_and_ingest_coverage.sh +++ b/src/dev/code_coverage/shell_scripts/generate_team_assignments_and_ingest_coverage.sh @@ -40,11 +40,5 @@ for x in jest functional; do node scripts/ingest_coverage.js --verbose --path ${COVERAGE_SUMMARY_FILE} --vcsInfoPath ./VCS_INFO.txt --teamAssignmentsPath $TEAM_ASSIGN_PATH done -# Need to override COVERAGE_INGESTION_KIBANA_ROOT since mocha json file has original intake worker path -COVERAGE_SUMMARY_FILE=target/kibana-coverage/mocha-combined/coverage-summary.json -export COVERAGE_INGESTION_KIBANA_ROOT=/dev/shm/workspace/kibana - -node scripts/ingest_coverage.js --verbose --path ${COVERAGE_SUMMARY_FILE} --vcsInfoPath ./VCS_INFO.txt --teamAssignmentsPath $TEAM_ASSIGN_PATH - echo "### Ingesting Code Coverage - Complete" echo "" diff --git a/test/scripts/checks/mocha_coverage.sh b/test/scripts/checks/mocha_coverage.sh deleted file mode 100755 index e1afad0ab775f..0000000000000 --- a/test/scripts/checks/mocha_coverage.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -yarn nyc --reporter=html --reporter=json-summary --report-dir=./target/kibana-coverage/mocha node scripts/mocha diff --git a/test/scripts/jenkins_unit.sh b/test/scripts/jenkins_unit.sh index 7384cec36b277..2edd66579f72f 100755 --- a/test/scripts/jenkins_unit.sh +++ b/test/scripts/jenkins_unit.sh @@ -44,8 +44,4 @@ else rename_coverage_file "oss-integration" echo "" echo "" - echo " -> Running mocha tests with coverage" - ./test/scripts/checks/mocha_coverage.sh - echo "" - echo "" fi diff --git a/vars/kibanaCoverage.groovy b/vars/kibanaCoverage.groovy index 521672e4bf48c..019eb8088dbfc 100644 --- a/vars/kibanaCoverage.groovy +++ b/vars/kibanaCoverage.groovy @@ -60,7 +60,6 @@ def uploadCoverageHtmls(prefix) { [ 'target/kibana-coverage/functional-combined', 'target/kibana-coverage/jest-combined', - 'target/kibana-coverage/mocha-combined', ].each { uploadWithVault(prefix, it) } } @@ -78,7 +77,6 @@ def prokLinks(title) { kibanaPipeline.bash(''' cat << EOF > src/dev/code_coverage/www/index_partial_2.html Latest Jest - Latest Mocha Latest FTR @@ -151,7 +149,6 @@ def generateReports(title) { . src/dev/code_coverage/shell_scripts/extract_archives.sh . src/dev/code_coverage/shell_scripts/fix_html_reports_parallel.sh . src/dev/code_coverage/shell_scripts/merge_jest_and_functional.sh - . src/dev/code_coverage/shell_scripts/copy_mocha_reports.sh # zip combined reports tar -czf kibana-coverage.tar.gz target/kibana-coverage/**/* """, title) From f8b1cdd81d950c9ba4930744ab0de59df55b1d40 Mon Sep 17 00:00:00 2001 From: Rudolf Meijering Date: Mon, 11 Jan 2021 21:38:54 +0100 Subject: [PATCH 15/64] Prevent kibana crashing when multiple processes start APM telemetry task in parallel (#87645) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/apm/server/lib/apm_telemetry/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts index 62fc16fb25053..6d91e64be034d 100644 --- a/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts +++ b/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts @@ -159,7 +159,7 @@ export async function createApmTelemetry({ logger.debug( `Stored telemetry is out of date. Task will run immediately. Stored: ${currentData.kibanaVersion}, expected: ${kibanaVersion}` ); - taskManagerStart.runNow(APM_TELEMETRY_TASK_NAME); + await taskManagerStart.runNow(APM_TELEMETRY_TASK_NAME); } } catch (err) { if (!SavedObjectsErrorHelpers.isNotFoundError(err)) { From 3ef7bd319737f088049450c978b85ae4ad12d0d5 Mon Sep 17 00:00:00 2001 From: Rudolf Meijering Date: Mon, 11 Jan 2021 21:39:23 +0100 Subject: [PATCH 16/64] Workaround https://github.com/elastic/elasticsearch/issues/67147 (#87615) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../migrationsv2/integration_tests/actions.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/server/saved_objects/migrationsv2/integration_tests/actions.test.ts b/src/core/server/saved_objects/migrationsv2/integration_tests/actions.test.ts index abda7cf82b121..1fd2e7352d8f7 100644 --- a/src/core/server/saved_objects/migrationsv2/integration_tests/actions.test.ts +++ b/src/core/server/saved_objects/migrationsv2/integration_tests/actions.test.ts @@ -908,8 +908,7 @@ describe('migration actions', () => { }); }); - // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/87160 - describe.skip('createIndex', () => { + describe('createIndex', () => { afterAll(async () => { await client.indices.delete({ index: 'yellow_then_green_index' }); }); @@ -936,6 +935,7 @@ describe('migration actions', () => { setTimeout(() => { client.indices.putSettings({ + index: 'yellow_then_green_index', body: { index: { number_of_replicas: 0, From 666af32be4077f0af78eb386dc9e2302abba1541 Mon Sep 17 00:00:00 2001 From: ymao1 Date: Mon, 11 Jan 2021 16:16:10 -0500 Subject: [PATCH 17/64] [Alerting] Showing confirmation modal on Alert Add/Edit when flyout closed without saving and changes made. (#86370) * Adding hasChanged check and showing confirmation modal if something has changed * Showing confirmation always on close * Adding functional test * Setting name and tags for APM alerts using initial values instead of setAlertProperty * Checking for alert param changes separately * Checking for alert param changes separately * Fixing functional test * Resetting initial alert params on alert type change * Fixing duplicate import * Cloning edited alert * PR fixes * PR fixes * Updating modal wording Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../alerting/alerting_flyout/index.tsx | 8 +- .../error_count_alert_trigger/index.tsx | 2 - .../alerting/get_initial_alert_values.test.ts | 25 +++ .../alerting/get_initial_alert_values.ts | 30 ++++ .../alerting/service_alert_trigger/index.tsx | 21 +-- .../service_alert_trigger.test.tsx | 1 - .../index.tsx | 2 - .../index.tsx | 4 - .../index.tsx | 2 - .../sections/alert_form/alert_add.tsx | 52 +++++- .../sections/alert_form/alert_edit.tsx | 29 +++- .../alert_form/confirm_alert_close.tsx | 52 ++++++ .../alert_form/has_alert_changed.test.ts | 164 ++++++++++++++++++ .../sections/alert_form/has_alert_changed.ts | 40 +++++ .../triggers_actions_ui/public/types.ts | 5 +- .../alert_create_flyout.ts | 13 ++ .../apps/triggers_actions_ui/details.ts | 2 + 17 files changed, 408 insertions(+), 44 deletions(-) create mode 100644 x-pack/plugins/apm/public/components/alerting/get_initial_alert_values.test.ts create mode 100644 x-pack/plugins/apm/public/components/alerting/get_initial_alert_values.ts create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/confirm_alert_close.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/has_alert_changed.test.ts create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/has_alert_changed.ts diff --git a/x-pack/plugins/apm/public/components/alerting/alerting_flyout/index.tsx b/x-pack/plugins/apm/public/components/alerting/alerting_flyout/index.tsx index 88a897d7baf50..83bbf49691be9 100644 --- a/x-pack/plugins/apm/public/components/alerting/alerting_flyout/index.tsx +++ b/x-pack/plugins/apm/public/components/alerting/alerting_flyout/index.tsx @@ -4,10 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ import React, { useCallback, useMemo } from 'react'; +import { useParams } from 'react-router-dom'; import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; import { AlertType } from '../../../../common/alert_types'; +import { getInitialAlertValues } from '../get_initial_alert_values'; import { TriggersAndActionsUIPublicPluginStart } from '../../../../../triggers_actions_ui/public'; - interface Props { addFlyoutVisible: boolean; setAddFlyoutVisibility: React.Dispatch>; @@ -20,10 +21,13 @@ interface KibanaDeps { export function AlertingFlyout(props: Props) { const { addFlyoutVisible, setAddFlyoutVisibility, alertType } = props; + const { serviceName } = useParams<{ serviceName?: string }>(); const { services: { triggersActionsUi }, } = useKibana(); + const initialValues = getInitialAlertValues(alertType, serviceName); + const onCloseAddFlyout = useCallback(() => setAddFlyoutVisibility(false), [ setAddFlyoutVisibility, ]); @@ -36,7 +40,9 @@ export function AlertingFlyout(props: Props) { onClose: onCloseAddFlyout, alertTypeId: alertType, canChangeTrigger: false, + initialValues, }), + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [alertType, onCloseAddFlyout, triggersActionsUi] ); return <>{addFlyoutVisible && addAlertFlyout}; diff --git a/x-pack/plugins/apm/public/components/alerting/error_count_alert_trigger/index.tsx b/x-pack/plugins/apm/public/components/alerting/error_count_alert_trigger/index.tsx index cce973f8587da..d7375d14e17cf 100644 --- a/x-pack/plugins/apm/public/components/alerting/error_count_alert_trigger/index.tsx +++ b/x-pack/plugins/apm/public/components/alerting/error_count_alert_trigger/index.tsx @@ -8,7 +8,6 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import { useParams } from 'react-router-dom'; import { ForLastExpression } from '../../../../../triggers_actions_ui/public'; -import { AlertType, ALERT_TYPES_CONFIG } from '../../../../common/alert_types'; import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; import { asInteger } from '../../../../common/utils/formatters'; import { useUrlParams } from '../../../context/url_params_context/use_url_params'; @@ -110,7 +109,6 @@ export function ErrorCountAlertTrigger(props: Props) { return ( { + expect(getInitialAlertValues(null, undefined)).toEqual({ tags: ['apm'] }); +}); + +test('handles valid alert type', () => { + const alertType = AlertType.ErrorCount; + expect(getInitialAlertValues(alertType, undefined)).toEqual({ + name: ALERT_TYPES_CONFIG[alertType].name, + tags: ['apm'], + }); + + expect(getInitialAlertValues(alertType, 'Service Name')).toEqual({ + name: `${ALERT_TYPES_CONFIG[alertType].name} | Service Name`, + tags: ['apm', `service.name:service name`], + }); +}); diff --git a/x-pack/plugins/apm/public/components/alerting/get_initial_alert_values.ts b/x-pack/plugins/apm/public/components/alerting/get_initial_alert_values.ts new file mode 100644 index 0000000000000..3655c9f90c4bf --- /dev/null +++ b/x-pack/plugins/apm/public/components/alerting/get_initial_alert_values.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { AlertType, ALERT_TYPES_CONFIG } from '../../../common/alert_types'; + +export function getInitialAlertValues( + alertType: AlertType | null, + serviceName: string | undefined +) { + const alertTypeName = alertType + ? ALERT_TYPES_CONFIG[alertType].name + : undefined; + const alertName = alertTypeName + ? serviceName + ? `${alertTypeName} | ${serviceName}` + : alertTypeName + : undefined; + const tags = ['apm']; + if (serviceName) { + tags.push(`service.name:${serviceName}`.toLowerCase()); + } + + return { + tags, + ...(alertName ? { name: alertName } : {}), + }; +} diff --git a/x-pack/plugins/apm/public/components/alerting/service_alert_trigger/index.tsx b/x-pack/plugins/apm/public/components/alerting/service_alert_trigger/index.tsx index 0a12f79bf61a9..a04679bcb689d 100644 --- a/x-pack/plugins/apm/public/components/alerting/service_alert_trigger/index.tsx +++ b/x-pack/plugins/apm/public/components/alerting/service_alert_trigger/index.tsx @@ -9,7 +9,6 @@ import React, { useEffect } from 'react'; import { useParams } from 'react-router-dom'; interface Props { - alertTypeName: string; setAlertParams: (key: string, value: any) => void; setAlertProperty: (key: string, value: any) => void; defaults: Record; @@ -20,14 +19,7 @@ interface Props { export function ServiceAlertTrigger(props: Props) { const { serviceName } = useParams<{ serviceName?: string }>(); - const { - fields, - setAlertParams, - setAlertProperty, - alertTypeName, - defaults, - chartPreview, - } = props; + const { fields, setAlertParams, defaults, chartPreview } = props; const params: Record = { ...defaults, @@ -36,17 +28,6 @@ export function ServiceAlertTrigger(props: Props) { useEffect(() => { // we only want to run this on mount to set default values - - const alertName = params.serviceName - ? `${alertTypeName} | ${params.serviceName}` - : alertTypeName; - setAlertProperty('name', alertName); - - const tags = ['apm']; - if (params.serviceName) { - tags.push(`service.name:${params.serviceName}`.toLowerCase()); - } - setAlertProperty('tags', tags); Object.keys(params).forEach((key) => { setAlertParams(key, params[key]); }); diff --git a/x-pack/plugins/apm/public/components/alerting/service_alert_trigger/service_alert_trigger.test.tsx b/x-pack/plugins/apm/public/components/alerting/service_alert_trigger/service_alert_trigger.test.tsx index 72611043bbed3..7f9a27e884e8e 100644 --- a/x-pack/plugins/apm/public/components/alerting/service_alert_trigger/service_alert_trigger.test.tsx +++ b/x-pack/plugins/apm/public/components/alerting/service_alert_trigger/service_alert_trigger.test.tsx @@ -18,7 +18,6 @@ describe('ServiceAlertTrigger', () => { expect(() => render( {}} diff --git a/x-pack/plugins/apm/public/components/alerting/transaction_duration_alert_trigger/index.tsx b/x-pack/plugins/apm/public/components/alerting/transaction_duration_alert_trigger/index.tsx index 22840bc2e6ed0..7c0a74f2e1b60 100644 --- a/x-pack/plugins/apm/public/components/alerting/transaction_duration_alert_trigger/index.tsx +++ b/x-pack/plugins/apm/public/components/alerting/transaction_duration_alert_trigger/index.tsx @@ -10,7 +10,6 @@ import React from 'react'; import { useParams } from 'react-router-dom'; import { useFetcher } from '../../../../../observability/public'; import { ForLastExpression } from '../../../../../triggers_actions_ui/public'; -import { ALERT_TYPES_CONFIG } from '../../../../common/alert_types'; import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; import { getDurationFormatter } from '../../../../common/utils/formatters'; import { TimeSeries } from '../../../../typings/timeseries'; @@ -203,7 +202,6 @@ export function TransactionDurationAlertTrigger(props: Props) { return ( > { @@ -66,8 +70,10 @@ const AlertAdd = ({ const [{ alert }, dispatch] = useReducer(alertReducer as InitialAlertReducer, { alert: initialAlert, }); + const [initialAlertParams, setInitialAlertParams] = useState({}); const [isSaving, setIsSaving] = useState(false); const [isConfirmAlertSaveModalOpen, setIsConfirmAlertSaveModalOpen] = useState(false); + const [isConfirmAlertCloseModalOpen, setIsConfirmAlertCloseModalOpen] = useState(false); const setAlert = (value: InitialAlert) => { dispatch({ command: { type: 'setAlert' }, payload: { key: 'alert', value } }); @@ -91,16 +97,35 @@ const AlertAdd = ({ } }, [alertTypeId]); - const closeFlyout = useCallback(() => { - setAlert(initialAlert); - onClose(); - }, [initialAlert, onClose]); + useEffect(() => { + if (isEmpty(alert.params) && !isEmpty(initialAlertParams)) { + // alert params are explicitly cleared when the alert type is cleared. + // clear the "initial" params in order to capture the + // default when a new alert type is selected + setInitialAlertParams({}); + } else if (isEmpty(initialAlertParams)) { + // captures the first change to the alert params, + // when consumers set a default value for the alert params + setInitialAlertParams(alert.params); + } + }, [alert.params, initialAlertParams, setInitialAlertParams]); + + const checkForChangesAndCloseFlyout = () => { + if ( + hasAlertChanged(alert, initialAlert, false) || + haveAlertParamsChanged(alert.params, initialAlertParams) + ) { + setIsConfirmAlertCloseModalOpen(true); + } else { + onClose(); + } + }; const saveAlertAndCloseFlyout = async () => { const savedAlert = await onSaveAlert(); setIsSaving(false); if (savedAlert) { - closeFlyout(); + onClose(); if (reloadAlerts) { reloadAlerts(); } @@ -142,7 +167,7 @@ const AlertAdd = ({ return ( @@ -214,6 +239,17 @@ const AlertAdd = ({ }} /> )} + {isConfirmAlertCloseModalOpen && ( + { + setIsConfirmAlertCloseModalOpen(false); + onClose(); + }} + onCancel={() => { + setIsConfirmAlertCloseModalOpen(false); + }} + /> + )} ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx index 024907c7bbbc4..6190853096f2e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx @@ -19,6 +19,7 @@ import { EuiCallOut, EuiSpacer, } from '@elastic/eui'; +import { cloneDeep } from 'lodash'; import { i18n } from '@kbn/i18n'; import { ActionTypeRegistryContract, Alert, AlertTypeRegistryContract } from '../../../types'; import { AlertForm, getAlertErrors, isValidAlert } from './alert_form'; @@ -27,6 +28,8 @@ import { updateAlert } from '../../lib/alert_api'; import { HealthCheck } from '../../components/health_check'; import { HealthContextProvider } from '../../context/health_context'; import { useKibana } from '../../../common/lib/kibana'; +import { ConfirmAlertClose } from './confirm_alert_close'; +import { hasAlertChanged } from './has_alert_changed'; import { getAlertWithInvalidatedFields } from '../../lib/value_validators'; export interface AlertEditProps> { @@ -47,13 +50,14 @@ export const AlertEdit = ({ metadata, }: AlertEditProps) => { const [{ alert }, dispatch] = useReducer(alertReducer as ConcreteAlertReducer, { - alert: initialAlert, + alert: cloneDeep(initialAlert), }); const [isSaving, setIsSaving] = useState(false); const [hasActionsDisabled, setHasActionsDisabled] = useState(false); const [hasActionsWithBrokenConnector, setHasActionsWithBrokenConnector] = useState( false ); + const [isConfirmAlertCloseModalOpen, setIsConfirmAlertCloseModalOpen] = useState(false); const { http, @@ -71,6 +75,14 @@ export const AlertEdit = ({ alertType ); + const checkForChangesAndCloseFlyout = () => { + if (hasAlertChanged(alert, initialAlert, true)) { + setIsConfirmAlertCloseModalOpen(true); + } else { + onClose(); + } + }; + async function onSaveAlert(): Promise { try { if (isValidAlert(alert, alertErrors, alertActionsErrors) && !hasActionsWithBrokenConnector) { @@ -107,7 +119,7 @@ export const AlertEdit = ({ return ( onClose()} + onClose={checkForChangesAndCloseFlyout} aria-labelledby="flyoutAlertEditTitle" size="m" maxWidth={620} @@ -160,7 +172,7 @@ export const AlertEdit = ({ onClose()} + onClick={() => checkForChangesAndCloseFlyout()} > {i18n.translate( 'xpack.triggersActionsUI.sections.alertEdit.cancelButtonLabel', @@ -200,6 +212,17 @@ export const AlertEdit = ({ + {isConfirmAlertCloseModalOpen && ( + { + setIsConfirmAlertCloseModalOpen(false); + onClose(); + }} + onCancel={() => { + setIsConfirmAlertCloseModalOpen(false); + }} + /> + )} ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/confirm_alert_close.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/confirm_alert_close.tsx new file mode 100644 index 0000000000000..3c0ab3faacf6f --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/confirm_alert_close.tsx @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React from 'react'; +import { EuiOverlayMask, EuiConfirmModal } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; + +interface Props { + onConfirm: () => void; + onCancel: () => void; +} + +export const ConfirmAlertClose: React.FC = ({ onConfirm, onCancel }) => { + return ( + + +

+ +

+
+
+ ); +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/has_alert_changed.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/has_alert_changed.test.ts new file mode 100644 index 0000000000000..73e33aa6f5cd5 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/has_alert_changed.test.ts @@ -0,0 +1,164 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { InitialAlert } from './alert_reducer'; +import { hasAlertChanged } from './has_alert_changed'; + +function createAlert(overrides = {}): InitialAlert { + return { + params: {}, + consumer: 'test', + alertTypeId: 'test', + schedule: { + interval: '1m', + }, + actions: [], + tags: [], + notifyWhen: 'onActionGroupChange', + ...overrides, + }; +} + +test('should return false for same alert', () => { + const a = createAlert(); + expect(hasAlertChanged(a, a, true)).toEqual(false); +}); + +test('should return true for different alert', () => { + const a = createAlert(); + const b = createAlert({ alertTypeId: 'differentTest' }); + expect(hasAlertChanged(a, b, true)).toEqual(true); +}); + +test('should correctly compare name field', () => { + // name field doesn't exist initially + const a = createAlert(); + // set name to actual value + const b = createAlert({ name: 'myAlert' }); + // set name to different value + const c = createAlert({ name: 'anotherAlert' }); + // set name to various empty/null/undefined states + const d = createAlert({ name: '' }); + const e = createAlert({ name: undefined }); + const f = createAlert({ name: null }); + + expect(hasAlertChanged(a, b, true)).toEqual(true); + expect(hasAlertChanged(a, c, true)).toEqual(true); + expect(hasAlertChanged(a, d, true)).toEqual(false); + expect(hasAlertChanged(a, e, true)).toEqual(false); + expect(hasAlertChanged(a, f, true)).toEqual(false); + + expect(hasAlertChanged(b, c, true)).toEqual(true); + expect(hasAlertChanged(b, d, true)).toEqual(true); + expect(hasAlertChanged(b, e, true)).toEqual(true); + expect(hasAlertChanged(b, f, true)).toEqual(true); + + expect(hasAlertChanged(c, d, true)).toEqual(true); + expect(hasAlertChanged(c, e, true)).toEqual(true); + expect(hasAlertChanged(c, f, true)).toEqual(true); + + expect(hasAlertChanged(d, e, true)).toEqual(false); + expect(hasAlertChanged(d, f, true)).toEqual(false); +}); + +test('should correctly compare alertTypeId field', () => { + const a = createAlert(); + + // set alertTypeId to different value + const b = createAlert({ alertTypeId: 'myAlertId' }); + // set alertTypeId to various empty/null/undefined states + const c = createAlert({ alertTypeId: '' }); + const d = createAlert({ alertTypeId: undefined }); + const e = createAlert({ alertTypeId: null }); + + expect(hasAlertChanged(a, b, true)).toEqual(true); + expect(hasAlertChanged(a, c, true)).toEqual(true); + expect(hasAlertChanged(a, d, true)).toEqual(true); + expect(hasAlertChanged(a, e, true)).toEqual(true); + + expect(hasAlertChanged(b, c, true)).toEqual(true); + expect(hasAlertChanged(b, d, true)).toEqual(true); + expect(hasAlertChanged(b, e, true)).toEqual(true); + + expect(hasAlertChanged(c, d, true)).toEqual(false); + expect(hasAlertChanged(c, e, true)).toEqual(false); + expect(hasAlertChanged(d, e, true)).toEqual(false); +}); + +test('should correctly compare throttle field', () => { + // throttle field doesn't exist initially + const a = createAlert(); + // set throttle to actual value + const b = createAlert({ throttle: '1m' }); + // set throttle to different value + const c = createAlert({ throttle: '1h' }); + // set throttle to various empty/null/undefined states + const d = createAlert({ throttle: '' }); + const e = createAlert({ throttle: undefined }); + const f = createAlert({ throttle: null }); + + expect(hasAlertChanged(a, b, true)).toEqual(true); + expect(hasAlertChanged(a, c, true)).toEqual(true); + expect(hasAlertChanged(a, d, true)).toEqual(false); + expect(hasAlertChanged(a, e, true)).toEqual(false); + expect(hasAlertChanged(a, f, true)).toEqual(false); + + expect(hasAlertChanged(b, c, true)).toEqual(true); + expect(hasAlertChanged(b, d, true)).toEqual(true); + expect(hasAlertChanged(b, e, true)).toEqual(true); + expect(hasAlertChanged(b, f, true)).toEqual(true); + + expect(hasAlertChanged(c, d, true)).toEqual(true); + expect(hasAlertChanged(c, e, true)).toEqual(true); + expect(hasAlertChanged(c, f, true)).toEqual(true); + + expect(hasAlertChanged(d, e, true)).toEqual(false); + expect(hasAlertChanged(d, f, true)).toEqual(false); +}); + +test('should correctly compare tags field', () => { + const a = createAlert(); + const b = createAlert({ tags: ['first'] }); + + expect(hasAlertChanged(a, b, true)).toEqual(true); +}); + +test('should correctly compare schedule field', () => { + const a = createAlert(); + const b = createAlert({ schedule: { interval: '3h' } }); + + expect(hasAlertChanged(a, b, true)).toEqual(true); +}); + +test('should correctly compare actions field', () => { + const a = createAlert(); + const b = createAlert({ + actions: [{ actionTypeId: 'action', group: 'group', id: 'actionId', params: {} }], + }); + + expect(hasAlertChanged(a, b, true)).toEqual(true); +}); + +test('should skip comparing params field if compareParams=false', () => { + const a = createAlert(); + const b = createAlert({ params: { newParam: 'value' } }); + + expect(hasAlertChanged(a, b, false)).toEqual(false); +}); + +test('should correctly compare params field if compareParams=true', () => { + const a = createAlert(); + const b = createAlert({ params: { newParam: 'value' } }); + + expect(hasAlertChanged(a, b, true)).toEqual(true); +}); + +test('should correctly compare notifyWhen field', () => { + const a = createAlert(); + const b = createAlert({ notifyWhen: 'onActiveAlert' }); + + expect(hasAlertChanged(a, b, true)).toEqual(true); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/has_alert_changed.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/has_alert_changed.ts new file mode 100644 index 0000000000000..806d4314dfe81 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/has_alert_changed.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import deepEqual from 'fast-deep-equal'; +import { pick } from 'lodash'; +import { AlertTypeParams } from '../../../types'; +import { InitialAlert } from './alert_reducer'; + +const DEEP_COMPARE_FIELDS = ['tags', 'schedule', 'actions', 'notifyWhen']; + +function getNonNullCompareFields(alert: InitialAlert) { + const { name, alertTypeId, throttle } = alert; + return { + ...(!!(name && name.length > 0) ? { name } : {}), + ...(!!(alertTypeId && alertTypeId.length > 0) ? { alertTypeId } : {}), + ...(!!(throttle && throttle.length > 0) ? { throttle } : {}), + }; +} + +export function hasAlertChanged(a: InitialAlert, b: InitialAlert, compareParams: boolean) { + // Deep compare these fields + let objectsAreEqual = deepEqual(pick(a, DEEP_COMPARE_FIELDS), pick(b, DEEP_COMPARE_FIELDS)); + if (compareParams) { + objectsAreEqual = objectsAreEqual && deepEqual(a.params, b.params); + } + + const nonNullCompareFieldsAreEqual = deepEqual( + getNonNullCompareFields(a), + getNonNullCompareFields(b) + ); + + return !objectsAreEqual || !nonNullCompareFieldsAreEqual; +} + +export function haveAlertParamsChanged(a: AlertTypeParams, b: AlertTypeParams) { + return !deepEqual(a, b); +} diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index f4dc4c3d4ef26..22969f6e4191c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -8,11 +8,12 @@ import type { DocLinksStart } from 'kibana/public'; import { ComponentType } from 'react'; import { ChartsPluginSetup } from 'src/plugins/charts/public'; import { DataPublicPluginStart } from 'src/plugins/data/public'; -import { ActionGroup, AlertActionParam, AlertTypeParams } from '../../alerts/common'; import { ActionType } from '../../actions/common'; import { TypeRegistry } from './application/type_registry'; import { AlertType as CommonAlertType } from '../../alerts/common'; import { + ActionGroup, + AlertActionParam, SanitizedAlert, AlertAction, AlertAggregations, @@ -22,6 +23,7 @@ import { RawAlertInstance, AlertingFrameworkHealth, AlertNotifyWhenType, + AlertTypeParams, } from '../../alerts/common'; // In Triggers and Actions we treat all `Alert`s as `SanitizedAlert` @@ -38,6 +40,7 @@ export { RawAlertInstance, AlertingFrameworkHealth, AlertNotifyWhenType, + AlertTypeParams, }; export { ActionType }; diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts index bb56b1a7b5269..352652d9601dc 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts @@ -204,5 +204,18 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const alertsToDelete = await getAlertsByName(alertName); await deleteAlerts(alertsToDelete.map((alertItem: { id: string }) => alertItem.id)); }); + + it('should show discard confirmation before closing flyout without saving', async () => { + await pageObjects.triggersActionsUI.clickCreateAlertButton(); + await testSubjects.click('cancelSaveAlertButton'); + await testSubjects.missingOrFail('confirmAlertCloseModal'); + + await pageObjects.triggersActionsUI.clickCreateAlertButton(); + await testSubjects.setValue('intervalInput', '10'); + await testSubjects.click('cancelSaveAlertButton'); + await testSubjects.existOrFail('confirmAlertCloseModal'); + await testSubjects.click('confirmAlertCloseModal > confirmModalCancelButton'); + await testSubjects.missingOrFail('confirmAlertCloseModal'); + }); }); }; diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts index 4b81d317b84f7..1ed0b38a238b8 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts @@ -298,6 +298,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); await testSubjects.click('cancelSaveEditedAlertButton'); + await testSubjects.existOrFail('confirmAlertCloseModal'); + await testSubjects.click('confirmAlertCloseModal > confirmModalConfirmButton'); await find.waitForDeletedByCssSelector('[data-test-subj="cancelSaveEditedAlertButton"]'); await editButton.click(); From 02f7956db3e3bcf6287ecc08f5e31e743d2cf3af Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 11 Jan 2021 16:35:02 -0500 Subject: [PATCH 18/64] [Uptime] Waterfall Chart - enable timings for local files by leveraging total time (#87424) * uptime waterfall enable timings for static files by leveraging total time * update cases for when their is no waterfall timing available * add showTooltip propertier to WaterfallDataSeriesConfigProperties * remove content downloading from the legend * add mime type to content downloading label Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../waterfall/data_formatting.test.ts | 434 +++++++++++++++++- .../step_detail/waterfall/data_formatting.ts | 69 ++- .../waterfall/waterfall_chart_wrapper.tsx | 2 +- .../waterfall/components/waterfall_chart.tsx | 10 +- .../monitor/synthetics/waterfall/types.ts | 3 +- 5 files changed, 505 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/data_formatting.test.ts b/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/data_formatting.test.ts index fff14376667b2..a58927dfbd12f 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/data_formatting.test.ts +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/data_formatting.test.ts @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { colourPalette } from './data_formatting'; +import { colourPalette, getSeriesAndDomain } from './data_formatting'; +import { NetworkItems } from './types'; describe('Palettes', () => { it('A colour palette comprising timing and mime type colours is correctly generated', () => { @@ -25,3 +26,434 @@ describe('Palettes', () => { }); }); }); + +describe('getSeriesAndDomain', () => { + const networkItems: NetworkItems = [ + { + timestamp: '2021-01-05T19:22:28.928Z', + method: 'GET', + url: 'https://unpkg.com/todomvc-app-css@2.0.4/index.css', + status: 200, + mimeType: 'text/css', + requestSentTime: 18098833.175, + requestStartTime: 18098835.439, + loadEndTime: 18098957.145, + timings: { + connect: 81.10800000213203, + wait: 34.577999998873565, + receive: 0.5520000013348181, + send: 0.3600000018195715, + total: 123.97000000055414, + proxy: -1, + blocked: 0.8540000017092098, + queueing: 2.263999998831423, + ssl: 55.38700000033714, + dns: 3.559999997378327, + }, + }, + { + timestamp: '2021-01-05T19:22:28.928Z', + method: 'GET', + url: 'https://unpkg.com/director@1.2.8/build/director.js', + status: 200, + mimeType: 'application/javascript', + requestSentTime: 18098833.537, + requestStartTime: 18098837.233999997, + loadEndTime: 18098977.648000002, + timings: { + blocked: 84.54599999822676, + receive: 3.068000001803739, + queueing: 3.69700000010198, + proxy: -1, + total: 144.1110000014305, + wait: 52.56100000042352, + connect: -1, + send: 0.2390000008745119, + ssl: -1, + dns: -1, + }, + }, + ]; + + const networkItemsWithoutFullTimings: NetworkItems = [ + networkItems[0], + { + timestamp: '2021-01-05T19:22:28.928Z', + method: 'GET', + url: 'file:///Users/dominiqueclarke/dev/synthetics/examples/todos/app/app.js', + status: 0, + mimeType: 'text/javascript', + requestSentTime: 18098834.097, + loadEndTime: 18098836.889999997, + timings: { + total: 2.7929999996558763, + blocked: -1, + ssl: -1, + wait: -1, + connect: -1, + dns: -1, + queueing: -1, + send: -1, + proxy: -1, + receive: -1, + }, + }, + ]; + + const networkItemsWithoutAnyTimings: NetworkItems = [ + { + timestamp: '2021-01-05T19:22:28.928Z', + method: 'GET', + url: 'file:///Users/dominiqueclarke/dev/synthetics/examples/todos/app/app.js', + status: 0, + mimeType: 'text/javascript', + requestSentTime: 18098834.097, + loadEndTime: 18098836.889999997, + timings: { + total: -1, + blocked: -1, + ssl: -1, + wait: -1, + connect: -1, + dns: -1, + queueing: -1, + send: -1, + proxy: -1, + receive: -1, + }, + }, + ]; + + const networkItemsWithoutTimingsObject: NetworkItems = [ + { + timestamp: '2021-01-05T19:22:28.928Z', + method: 'GET', + url: 'file:///Users/dominiqueclarke/dev/synthetics/examples/todos/app/app.js', + status: 0, + mimeType: 'text/javascript', + requestSentTime: 18098834.097, + loadEndTime: 18098836.889999997, + }, + ]; + + it('formats timings', () => { + const actual = getSeriesAndDomain(networkItems); + expect(actual).toMatchInlineSnapshot(` + Object { + "domain": Object { + "max": 140.7760000010603, + "min": 0, + }, + "series": Array [ + Object { + "config": Object { + "colour": "#b9a888", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#b9a888", + "value": "Queued / Blocked: 0.854ms", + }, + }, + "x": 0, + "y": 0.8540000017092098, + "y0": 0, + }, + Object { + "config": Object { + "colour": "#54b399", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#54b399", + "value": "DNS: 3.560ms", + }, + }, + "x": 0, + "y": 4.413999999087537, + "y0": 0.8540000017092098, + }, + Object { + "config": Object { + "colour": "#da8b45", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#da8b45", + "value": "Connecting: 25.721ms", + }, + }, + "x": 0, + "y": 30.135000000882428, + "y0": 4.413999999087537, + }, + Object { + "config": Object { + "colour": "#edc5a2", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#edc5a2", + "value": "TLS: 55.387ms", + }, + }, + "x": 0, + "y": 85.52200000121957, + "y0": 30.135000000882428, + }, + Object { + "config": Object { + "colour": "#d36086", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#d36086", + "value": "Sending request: 0.360ms", + }, + }, + "x": 0, + "y": 85.88200000303914, + "y0": 85.52200000121957, + }, + Object { + "config": Object { + "colour": "#b0c9e0", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#b0c9e0", + "value": "Waiting (TTFB): 34.578ms", + }, + }, + "x": 0, + "y": 120.4600000019127, + "y0": 85.88200000303914, + }, + Object { + "config": Object { + "colour": "#ca8eae", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#ca8eae", + "value": "Content downloading (CSS): 0.552ms", + }, + }, + "x": 0, + "y": 121.01200000324752, + "y0": 120.4600000019127, + }, + Object { + "config": Object { + "colour": "#b9a888", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#b9a888", + "value": "Queued / Blocked: 84.546ms", + }, + }, + "x": 1, + "y": 84.90799999795854, + "y0": 0.3619999997317791, + }, + Object { + "config": Object { + "colour": "#d36086", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#d36086", + "value": "Sending request: 0.239ms", + }, + }, + "x": 1, + "y": 85.14699999883305, + "y0": 84.90799999795854, + }, + Object { + "config": Object { + "colour": "#b0c9e0", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#b0c9e0", + "value": "Waiting (TTFB): 52.561ms", + }, + }, + "x": 1, + "y": 137.70799999925657, + "y0": 85.14699999883305, + }, + Object { + "config": Object { + "colour": "#9170b8", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#9170b8", + "value": "Content downloading (JS): 3.068ms", + }, + }, + "x": 1, + "y": 140.7760000010603, + "y0": 137.70799999925657, + }, + ], + } + `); + }); + + it('handles formatting when only total timing values are available', () => { + const actual = getSeriesAndDomain(networkItemsWithoutFullTimings); + expect(actual).toMatchInlineSnapshot(` + Object { + "domain": Object { + "max": 121.01200000324752, + "min": 0, + }, + "series": Array [ + Object { + "config": Object { + "colour": "#b9a888", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#b9a888", + "value": "Queued / Blocked: 0.854ms", + }, + }, + "x": 0, + "y": 0.8540000017092098, + "y0": 0, + }, + Object { + "config": Object { + "colour": "#54b399", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#54b399", + "value": "DNS: 3.560ms", + }, + }, + "x": 0, + "y": 4.413999999087537, + "y0": 0.8540000017092098, + }, + Object { + "config": Object { + "colour": "#da8b45", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#da8b45", + "value": "Connecting: 25.721ms", + }, + }, + "x": 0, + "y": 30.135000000882428, + "y0": 4.413999999087537, + }, + Object { + "config": Object { + "colour": "#edc5a2", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#edc5a2", + "value": "TLS: 55.387ms", + }, + }, + "x": 0, + "y": 85.52200000121957, + "y0": 30.135000000882428, + }, + Object { + "config": Object { + "colour": "#d36086", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#d36086", + "value": "Sending request: 0.360ms", + }, + }, + "x": 0, + "y": 85.88200000303914, + "y0": 85.52200000121957, + }, + Object { + "config": Object { + "colour": "#b0c9e0", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#b0c9e0", + "value": "Waiting (TTFB): 34.578ms", + }, + }, + "x": 0, + "y": 120.4600000019127, + "y0": 85.88200000303914, + }, + Object { + "config": Object { + "colour": "#ca8eae", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#ca8eae", + "value": "Content downloading (CSS): 0.552ms", + }, + }, + "x": 0, + "y": 121.01200000324752, + "y0": 120.4600000019127, + }, + Object { + "config": Object { + "colour": "#9170b8", + "showTooltip": true, + "tooltipProps": Object { + "colour": "#9170b8", + "value": "Content downloading (JS): 2.793ms", + }, + }, + "x": 1, + "y": 3.714999998046551, + "y0": 0.9219999983906746, + }, + ], + } + `); + }); + + it('handles formatting when there is no timing information available', () => { + const actual = getSeriesAndDomain(networkItemsWithoutAnyTimings); + expect(actual).toMatchInlineSnapshot(` + Object { + "domain": Object { + "max": 0, + "min": 0, + }, + "series": Array [ + Object { + "config": Object { + "colour": "", + "showTooltip": false, + "tooltipProps": undefined, + }, + "x": 0, + "y": 0, + "y0": 0, + }, + ], + } + `); + }); + + it('handles formatting when the timings object is undefined', () => { + const actual = getSeriesAndDomain(networkItemsWithoutTimingsObject); + expect(actual).toMatchInlineSnapshot(` + Object { + "domain": Object { + "max": 0, + "min": 0, + }, + "series": Array [ + Object { + "config": Object { + "showTooltip": false, + }, + "x": 0, + "y": 0, + "y0": 0, + }, + ], + } + `); + }); +}); diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/data_formatting.ts b/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/data_formatting.ts index 7c6e176315b5b..43fa93fa5f6f2 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/data_formatting.ts +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/data_formatting.ts @@ -38,6 +38,23 @@ const getColourForMimeType = (mimeType?: string) => { return colourPalette[key]; }; +const getFriendlyTooltipValue = ({ + value, + timing, + mimeType, +}: { + value: number; + timing: Timings; + mimeType?: string; +}) => { + let label = FriendlyTimingLabels[timing]; + if (timing === Timings.Receive && mimeType) { + const formattedMimeType: MimeType = MimeTypesMap[mimeType]; + label += ` (${FriendlyMimetypeLabels[formattedMimeType]})`; + } + return `${label}: ${formatValueForDisplay(value)}ms`; +}; + export const getSeriesAndDomain = (items: NetworkItems) => { const getValueForOffset = (item: NetworkItem) => { return item.requestSentTime; @@ -61,16 +78,26 @@ export const getSeriesAndDomain = (items: NetworkItems) => { }; const series = items.reduce((acc, item, index) => { - if (!item.timings) return acc; + if (!item.timings) { + acc.push({ + x: index, + y0: 0, + y: 0, + config: { + showTooltip: false, + }, + }); + return acc; + } const offsetValue = getValueForOffset(item); + const mimeTypeColour = getColourForMimeType(item.mimeType); let currentOffset = offsetValue - zeroOffset; TIMING_ORDER.forEach((timing) => { const value = getValue(item.timings, timing); - const colour = - timing === Timings.Receive ? getColourForMimeType(item.mimeType) : colourPalette[timing]; + const colour = timing === Timings.Receive ? mimeTypeColour : colourPalette[timing]; if (value && value >= 0) { const y = currentOffset + value; @@ -80,10 +107,13 @@ export const getSeriesAndDomain = (items: NetworkItems) => { y, config: { colour, + showTooltip: true, tooltipProps: { - value: `${FriendlyTimingLabels[timing]}: ${formatValueForDisplay( - y - currentOffset - )}ms`, + value: getFriendlyTooltipValue({ + value: y - currentOffset, + timing, + mimeType: item.mimeType, + }), colour, }, }, @@ -91,6 +121,33 @@ export const getSeriesAndDomain = (items: NetworkItems) => { currentOffset = y; } }); + + /* if no specific timing values are found, use the total time + * if total time is not available use 0, set showTooltip to false, + * and omit tooltip props */ + if (!acc.find((entry) => entry.x === index)) { + const total = item.timings.total; + const hasTotal = total !== -1; + acc.push({ + x: index, + y0: hasTotal ? currentOffset : 0, + y: hasTotal ? currentOffset + item.timings.total : 0, + config: { + colour: hasTotal ? mimeTypeColour : '', + showTooltip: hasTotal, + tooltipProps: hasTotal + ? { + value: getFriendlyTooltipValue({ + value: total, + timing: Timings.Receive, + mimeType: item.mimeType, + }), + colour: mimeTypeColour, + } + : undefined, + }, + }); + } return acc; }, []); diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx b/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx index 7aa5a22849321..a84765c4ea154 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx @@ -70,7 +70,7 @@ export const WaterfallChartWrapper: React.FC = ({ data }) => { sidebarItems={sidebarItems} legendItems={legendItems} renderTooltipItem={(tooltipProps) => { - return {tooltipProps.value}; + return {tooltipProps?.value}; }} > { +const Tooltip = (tooltipInfo: TooltipInfo) => { const { data, renderTooltipItem } = useWaterfallContext(); const relevantItems = data.filter((item) => { - return item.x === header?.value; + return ( + item.x === tooltipInfo.header?.value && item.config.showTooltip && item.config.tooltipProps + ); }); - return ( + return relevantItems.length ? ( {relevantItems.map((item, index) => { @@ -52,7 +54,7 @@ const Tooltip = ({ header }: TooltipInfo) => { })} - ); + ) : null; }; export type RenderItem = (item: I, index: number) => JSX.Element; diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/types.ts b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/types.ts index d6901fb482599..fd7f9effcd193 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/types.ts +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/types.ts @@ -11,7 +11,8 @@ interface PlotProperties { } export interface WaterfallDataSeriesConfigProperties { - tooltipProps: Record; + tooltipProps?: Record; + showTooltip: boolean; } export type WaterfallDataEntry = PlotProperties & { From cf086b678b9e6054bc3dd0116498bbadc0a35d6c Mon Sep 17 00:00:00 2001 From: Constance Date: Mon, 11 Jan 2021 13:52:24 -0800 Subject: [PATCH 19/64] [App Search] Minor const cleanup (#87885) * DRY out repeated DOCUMENTS_TITLE * Move temporary title const's in engine folder to their own respective folders - might as well get it set up early + prevents us from forgetting to clean this up later * Update engine nav & engine router files --- .../components/analytics/constants.ts | 5 ++ .../app_search/components/analytics/index.ts | 7 +++ .../components/api_logs/constants.ts | 5 ++ .../app_search/components/api_logs/index.ts | 7 +++ .../components/crawler/constants.ts | 12 +++++ .../app_search/components/crawler/index.ts | 7 +++ .../components/curations/constants.ts | 12 +++++ .../app_search/components/curations/index.ts | 7 +++ .../app_search/components/documents/index.ts | 1 + .../app_search/components/engine/constants.ts | 50 ------------------- .../components/engine/engine_nav.tsx | 22 ++++---- .../components/engine/engine_router.tsx | 13 +---- .../components/relevance_tuning/constants.ts | 12 +++++ .../components/relevance_tuning/index.ts | 7 +++ .../components/result_settings/constants.ts | 12 +++++ .../components/result_settings/index.ts | 7 +++ .../app_search/components/schema/constants.ts | 11 ++++ .../app_search/components/schema/index.ts | 7 +++ .../components/search_ui/constants.ts | 12 +++++ .../app_search/components/search_ui/index.ts | 7 +++ .../components/synonyms/constants.ts | 12 +++++ .../app_search/components/synonyms/index.ts | 7 +++ .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 24 files changed, 168 insertions(+), 76 deletions(-) create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/index.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/index.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/constants.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/index.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/constants.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/index.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/constants.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/constants.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/index.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/constants.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/index.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/constants.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/index.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/constants.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/index.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/constants.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/index.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/constants.ts index 51ae11ad2ab82..1e25582e3d569 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/constants.ts @@ -6,6 +6,11 @@ import { i18n } from '@kbn/i18n'; +export const ANALYTICS_TITLE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.analytics.title', + { defaultMessage: 'Analytics' } +); + export const TOTAL_DOCUMENTS = i18n.translate( 'xpack.enterpriseSearch.appSearch.engine.analytics.totalDocuments', { defaultMessage: 'Total documents' } diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/index.ts new file mode 100644 index 0000000000000..7cddef645e838 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/index.ts @@ -0,0 +1,7 @@ +/* + * 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 { ANALYTICS_TITLE } from './constants'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/constants.ts index 6fd60b7a34ebc..0a12f872f18f4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/constants.ts @@ -6,6 +6,11 @@ import { i18n } from '@kbn/i18n'; +export const API_LOGS_TITLE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.apiLogs.title', + { defaultMessage: 'API Logs' } +); + export const RECENT_API_EVENTS = i18n.translate( 'xpack.enterpriseSearch.appSearch.engine.apiLogs.recent', { defaultMessage: 'Recent API events' } diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/index.ts new file mode 100644 index 0000000000000..72cd9efa887c3 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/index.ts @@ -0,0 +1,7 @@ +/* + * 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 { API_LOGS_TITLE } from './constants'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/constants.ts new file mode 100644 index 0000000000000..777d75600a279 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/constants.ts @@ -0,0 +1,12 @@ +/* + * 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'; + +export const CRAWLER_TITLE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.crawler.title', + { defaultMessage: 'Crawler' } +); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/index.ts new file mode 100644 index 0000000000000..f5b81c318ed56 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/index.ts @@ -0,0 +1,7 @@ +/* + * 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 { CRAWLER_TITLE } from './constants'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/constants.ts new file mode 100644 index 0000000000000..3b88d2c4983d4 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/constants.ts @@ -0,0 +1,12 @@ +/* + * 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'; + +export const CURATIONS_TITLE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.curations.title', + { defaultMessage: 'Curations' } +); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/index.ts new file mode 100644 index 0000000000000..ecb9c223e4b6e --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/index.ts @@ -0,0 +1,7 @@ +/* + * 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 { CURATIONS_TITLE } from './constants'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/index.ts index b67e444939c0e..113259b7bd899 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/index.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +export { DOCUMENTS_TITLE } from './constants'; export { DocumentDetailLogic } from './document_detail_logic'; export { DocumentsLogic } from './documents_logic'; export { Documents } from './documents'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/constants.ts deleted file mode 100644 index 9ce524038075b..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/constants.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { i18n } from '@kbn/i18n'; - -// TODO: It's very likely that we'll move these i18n constants to their respective component -// folders once those are migrated over. This is a temporary way of DRYing them out for now. - -export const ANALYTICS_TITLE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.engine.analytics.title', - { defaultMessage: 'Analytics' } -); -export const DOCUMENTS_TITLE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.engine.documents.title', - { defaultMessage: 'Documents' } -); -export const SCHEMA_TITLE = i18n.translate('xpack.enterpriseSearch.appSearch.engine.schema.title', { - defaultMessage: 'Schema', -}); -export const CRAWLER_TITLE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.engine.crawler.title', - { defaultMessage: 'Crawler' } -); -export const RELEVANCE_TUNING_TITLE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.title', - { defaultMessage: 'Relevance Tuning' } -); -export const SYNONYMS_TITLE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.engine.synonyms.title', - { defaultMessage: 'Synonyms' } -); -export const CURATIONS_TITLE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.engine.curations.title', - { defaultMessage: 'Curations' } -); -export const RESULT_SETTINGS_TITLE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.engine.resultSettings.title', - { defaultMessage: 'Result Settings' } -); -export const SEARCH_UI_TITLE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.engine.searchUI.title', - { defaultMessage: 'Search UI' } -); -export const API_LOGS_TITLE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.engine.apiLogs.title', - { defaultMessage: 'API Logs' } -); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx index 0fed7cd0fc8fc..418ab33457d0a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx @@ -29,18 +29,16 @@ import { import { getAppSearchUrl } from '../../../shared/enterprise_search_url'; import { ENGINES_TITLE } from '../engines'; import { OVERVIEW_TITLE } from '../engine_overview'; -import { - ANALYTICS_TITLE, - DOCUMENTS_TITLE, - SCHEMA_TITLE, - CRAWLER_TITLE, - RELEVANCE_TUNING_TITLE, - SYNONYMS_TITLE, - CURATIONS_TITLE, - RESULT_SETTINGS_TITLE, - SEARCH_UI_TITLE, - API_LOGS_TITLE, -} from './constants'; +import { ANALYTICS_TITLE } from '../analytics'; +import { DOCUMENTS_TITLE } from '../documents'; +import { SCHEMA_TITLE } from '../schema'; +import { CRAWLER_TITLE } from '../crawler'; +import { RELEVANCE_TUNING_TITLE } from '../relevance_tuning'; +import { SYNONYMS_TITLE } from '../synonyms'; +import { CURATIONS_TITLE } from '../curations'; +import { RESULT_SETTINGS_TITLE } from '../result_settings'; +import { SEARCH_UI_TITLE } from '../search_ui'; +import { API_LOGS_TITLE } from '../api_logs'; import { EngineLogic } from './'; import { EngineDetails } from './types'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx index ce7675cef9bb1..1d2f3f640f341 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx @@ -33,18 +33,7 @@ import { } from '../../routes'; import { ENGINES_TITLE } from '../engines'; import { OVERVIEW_TITLE } from '../engine_overview'; -import { - ANALYTICS_TITLE, - // DOCUMENTS_TITLE, - // SCHEMA_TITLE, - // CRAWLER_TITLE, - // RELEVANCE_TUNING_TITLE, - // SYNONYMS_TITLE, - // CURATIONS_TITLE, - // RESULT_SETTINGS_TITLE, - // SEARCH_UI_TITLE, - // API_LOGS_TITLE, -} from './constants'; +import { ANALYTICS_TITLE } from '../analytics'; import { Loading } from '../../../shared/loading'; import { EngineOverview } from '../engine_overview'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/constants.ts new file mode 100644 index 0000000000000..b993b017f7b34 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/constants.ts @@ -0,0 +1,12 @@ +/* + * 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'; + +export const RELEVANCE_TUNING_TITLE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.title', + { defaultMessage: 'Relevance Tuning' } +); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/index.ts new file mode 100644 index 0000000000000..40f3ddbf2899b --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/index.ts @@ -0,0 +1,7 @@ +/* + * 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 { RELEVANCE_TUNING_TITLE } from './constants'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/constants.ts new file mode 100644 index 0000000000000..6609f2c69099a --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/constants.ts @@ -0,0 +1,12 @@ +/* + * 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'; + +export const RESULT_SETTINGS_TITLE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.resultSettings.title', + { defaultMessage: 'Result Settings' } +); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/index.ts new file mode 100644 index 0000000000000..c9d8bacc39dd2 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/index.ts @@ -0,0 +1,7 @@ +/* + * 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 { RESULT_SETTINGS_TITLE } from './constants'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/constants.ts new file mode 100644 index 0000000000000..dfe87b396aac8 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/constants.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const SCHEMA_TITLE = i18n.translate('xpack.enterpriseSearch.appSearch.engine.schema.title', { + defaultMessage: 'Schema', +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/index.ts new file mode 100644 index 0000000000000..02d534a9c37cc --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/index.ts @@ -0,0 +1,7 @@ +/* + * 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 { SCHEMA_TITLE } from './constants'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/constants.ts new file mode 100644 index 0000000000000..9d79924b5ffed --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/constants.ts @@ -0,0 +1,12 @@ +/* + * 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'; + +export const SEARCH_UI_TITLE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.searchUI.title', + { defaultMessage: 'Search UI' } +); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/index.ts new file mode 100644 index 0000000000000..2c3c122e7c034 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/index.ts @@ -0,0 +1,7 @@ +/* + * 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 { SEARCH_UI_TITLE } from './constants'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/constants.ts new file mode 100644 index 0000000000000..ece979b8db00d --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/constants.ts @@ -0,0 +1,12 @@ +/* + * 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'; + +export const SYNONYMS_TITLE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.synonyms.title', + { defaultMessage: 'Synonyms' } +); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/index.ts new file mode 100644 index 0000000000000..bc4388eb1fbc4 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/index.ts @@ -0,0 +1,7 @@ +/* + * 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 { SYNONYMS_TITLE } from './constants'; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 06fa5f451bfe1..de1e26580d87f 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -7241,7 +7241,6 @@ "xpack.enterpriseSearch.appSearch.engine.apiLogs.title": "API ログ", "xpack.enterpriseSearch.appSearch.engine.crawler.title": "Crawler", "xpack.enterpriseSearch.appSearch.engine.curations.title": "キュレーション", - "xpack.enterpriseSearch.appSearch.engine.documents.title": "ドキュメント", "xpack.enterpriseSearch.appSearch.engine.metaEngineBadge": "メタエンジン", "xpack.enterpriseSearch.appSearch.engine.notFound": "名前「{engineName}」のエンジンが見つかりませんでした。", "xpack.enterpriseSearch.appSearch.engine.overview.analyticsLink": "分析を表示", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index aec87aac84083..7169197a7628e 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -7260,7 +7260,6 @@ "xpack.enterpriseSearch.appSearch.engine.apiLogs.title": "API 日志", "xpack.enterpriseSearch.appSearch.engine.crawler.title": "网络爬虫", "xpack.enterpriseSearch.appSearch.engine.curations.title": "策展", - "xpack.enterpriseSearch.appSearch.engine.documents.title": "文档", "xpack.enterpriseSearch.appSearch.engine.metaEngineBadge": "元引擎", "xpack.enterpriseSearch.appSearch.engine.notFound": "找不到名为“{engineName}”的引擎。", "xpack.enterpriseSearch.appSearch.engine.overview.analyticsLink": "查看分析", From 7cd1fa3167507a33da8434a5d547bdf9e9fad4a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Mon, 11 Jan 2021 23:43:42 +0100 Subject: [PATCH 20/64] [APM] Cleanup: Remove `isValidCoordinateValue` and `getResponseTimeTooltipFormatter` (#87836) --- .../apm/common/utils/formatters/formatters.ts | 12 ++++++++-- .../components/shared/ManagedTable/index.tsx | 4 ++-- .../shared/charts/metrics_chart/index.tsx | 11 ++++----- .../charts/transaction_charts/helper.test.ts | 23 ++++--------------- .../charts/transaction_charts/helper.tsx | 16 ++----------- .../public/utils/isValidCoordinateValue.ts | 9 -------- 6 files changed, 23 insertions(+), 52 deletions(-) delete mode 100644 x-pack/plugins/apm/public/utils/isValidCoordinateValue.ts diff --git a/x-pack/plugins/apm/common/utils/formatters/formatters.ts b/x-pack/plugins/apm/common/utils/formatters/formatters.ts index 50ce9db096610..7b21a686209ae 100644 --- a/x-pack/plugins/apm/common/utils/formatters/formatters.ts +++ b/x-pack/plugins/apm/common/utils/formatters/formatters.ts @@ -8,11 +8,19 @@ import { Maybe } from '../../../typings/common'; import { NOT_AVAILABLE_LABEL } from '../../i18n'; import { isFiniteNumber } from '../is_finite_number'; -export function asDecimal(value: number) { +export function asDecimal(value?: number | null) { + if (!isFiniteNumber(value)) { + return NOT_AVAILABLE_LABEL; + } + return numeral(value).format('0,0.0'); } -export function asInteger(value: number) { +export function asInteger(value?: number | null) { + if (!isFiniteNumber(value)) { + return NOT_AVAILABLE_LABEL; + } + return numeral(value).format('0,0'); } diff --git a/x-pack/plugins/apm/public/components/shared/ManagedTable/index.tsx b/x-pack/plugins/apm/public/components/shared/ManagedTable/index.tsx index 6f62fd24e71ea..8033b6415319e 100644 --- a/x-pack/plugins/apm/public/components/shared/ManagedTable/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/ManagedTable/index.tsx @@ -102,8 +102,8 @@ function UnoptimizedManagedTable(props: Props) { ...toQuery(history.location.search), page: options.page.index, pageSize: options.page.size, - sortField: options.sort!.field, - sortDirection: options.sort!.direction, + sortField: options.sort?.field, + sortDirection: options.sort?.direction, }), }); }, diff --git a/x-pack/plugins/apm/public/components/shared/charts/metrics_chart/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/metrics_chart/index.tsx index 506c27051b511..a135bff14d3c6 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/metrics_chart/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/metrics_chart/index.tsx @@ -16,7 +16,6 @@ import { import { GenericMetricsChart } from '../../../../../server/lib/metrics/transform_metrics_chart'; import { Maybe } from '../../../../../typings/common'; import { FETCH_STATUS } from '../../../../hooks/use_fetcher'; -import { isValidCoordinateValue } from '../../../../utils/isValidCoordinateValue'; import { TimeseriesChart } from '../timeseries_chart'; function getYTickFormatter(chart: GenericMetricsChart) { @@ -33,15 +32,13 @@ function getYTickFormatter(chart: GenericMetricsChart) { return (y: Maybe) => asPercent(y || 0, 1); } case 'time': { - return (y: Maybe) => asDuration(y); + return asDuration; } case 'integer': { - return (y: Maybe) => - isValidCoordinateValue(y) ? asInteger(y) : y; + return asInteger; } default: { - return (y: Maybe) => - isValidCoordinateValue(y) ? asDecimal(y) : y; + return asDecimal; } } } @@ -63,7 +60,7 @@ export function MetricsChart({ chart, fetchStatus }: Props) { fetchStatus={fetchStatus} id={chart.key} timeseries={chart.series} - yLabelFormat={getYTickFormatter(chart) as (y: number) => string} + yLabelFormat={getYTickFormatter(chart)} /> ); diff --git a/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/helper.test.ts b/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/helper.test.ts index e92ecd2aeefd8..6d7e279f47e04 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/helper.test.ts +++ b/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/helper.test.ts @@ -4,11 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - getResponseTimeTickFormatter, - getResponseTimeTooltipFormatter, - getMaxY, -} from './helper'; +import { getResponseTimeTickFormatter, getMaxY } from './helper'; import { TimeSeries, Coordinate } from '../../../../../typings/timeseries'; import { @@ -25,35 +21,26 @@ describe('transaction chart helper', () => { '1.0 min' ); }); + it('formattes time tick in seconds', () => { const formatter = getDurationFormatter(toMicroseconds(11, 'seconds')); const timeTickFormatter = getResponseTimeTickFormatter(formatter); expect(timeTickFormatter(toMicroseconds(6, 'seconds'))).toEqual('6.0 s'); }); }); - describe('getResponseTimeTooltipFormatter', () => { - const formatter = getDurationFormatter(toMicroseconds(11, 'minutes')); - const tooltipFormatter = getResponseTimeTooltipFormatter(formatter); - it("doesn't format invalid y coordinate", () => { - expect(tooltipFormatter({ x: 1, y: undefined })).toEqual('N/A'); - expect(tooltipFormatter({ x: 1, y: null })).toEqual('N/A'); - }); - it('formattes tooltip in minutes', () => { - expect( - tooltipFormatter({ x: 1, y: toMicroseconds(60, 'seconds') }) - ).toEqual('1.0 min'); - }); - }); + describe('getMaxY', () => { it('returns zero when empty time series', () => { expect(getMaxY([])).toEqual(0); }); + it('returns zero for invalid y coordinate', () => { const timeSeries = ([ { data: [{ x: 1 }, { x: 2 }, { x: 3, y: -1 }] }, ] as unknown) as Array>; expect(getMaxY(timeSeries)).toEqual(0); }); + it('returns the max y coordinate', () => { const timeSeries = ([ { diff --git a/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/helper.tsx b/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/helper.tsx index 4d2a60c494178..a8583b4b0dada 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/helper.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/helper.tsx @@ -4,23 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n'; -import { TimeFormatter } from '../../../../../common/utils/formatters'; import { Coordinate, TimeSeries } from '../../../../../typings/timeseries'; -import { isValidCoordinateValue } from '../../../../utils/isValidCoordinateValue'; +import { TimeFormatter } from '../../../../../common/utils/formatters'; export function getResponseTimeTickFormatter(formatter: TimeFormatter) { - return (t: number) => { - return formatter(t).formatted; - }; -} - -export function getResponseTimeTooltipFormatter(formatter: TimeFormatter) { - return (coordinate: Coordinate) => { - return isValidCoordinateValue(coordinate.y) - ? formatter(coordinate.y).formatted - : NOT_AVAILABLE_LABEL; - }; + return (t: number) => formatter(t).formatted; } export function getMaxY(timeSeries?: Array>) { diff --git a/x-pack/plugins/apm/public/utils/isValidCoordinateValue.ts b/x-pack/plugins/apm/public/utils/isValidCoordinateValue.ts deleted file mode 100644 index c36efc232b782..0000000000000 --- a/x-pack/plugins/apm/public/utils/isValidCoordinateValue.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { Maybe } from '../../typings/common'; - -export const isValidCoordinateValue = (value: Maybe): value is number => - value !== null && value !== undefined; From 1e7c3f88ec2e580d4b31465aa2ccfec1da5254ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Kopyci=C5=84ski?= Date: Tue, 12 Jan 2021 00:09:38 +0100 Subject: [PATCH 21/64] =?UTF-8?q?[Security=20Solution]=20Fix=20sorting=20o?= =?UTF-8?q?n=20unmapped=20fields=20in=20Timeline=20Events=E2=80=A6=20(#872?= =?UTF-8?q?41)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Security Solution] Fix sorting on unmapped fields in Timeline Events table * set unmapped_type to the column type * add missing types * Update saved_object_mappings.ts Co-authored-by: Xavier Mouligneau <189600+XavierM@users.noreply.github.com> --- .../common/search_strategy/timeline/index.ts | 6 +++++- .../common/types/timeline/index.ts | 1 + .../events_viewer/events_viewer.test.tsx | 1 + .../components/events_viewer/events_viewer.tsx | 3 ++- .../public/common/components/page/index.tsx | 5 +++++ .../public/common/mock/global_state.ts | 2 +- .../public/common/mock/timeline_results.ts | 7 ++++--- .../components/alerts_table/actions.test.tsx | 2 ++ .../components/open_timeline/__mocks__/index.ts | 2 ++ .../components/open_timeline/helpers.test.ts | 17 ++++++++++++++++- .../__snapshots__/index.test.tsx.snap | 2 ++ .../body/column_headers/default_headers.ts | 1 + .../header/__snapshots__/index.test.tsx.snap | 5 +++++ .../body/column_headers/header/index.test.tsx | 13 ++++++++++++- .../body/column_headers/header/index.tsx | 3 +++ .../timeline/body/column_headers/index.test.tsx | 15 ++++++++++++--- .../timeline/body/column_headers/index.tsx | 3 ++- .../components/timeline/body/index.test.tsx | 1 + .../components/timeline/body/sort/index.ts | 1 + .../__snapshots__/index.test.tsx.snap | 1 + .../timeline/pinned_tab_content/index.test.tsx | 1 + .../timeline/pinned_tab_content/index.tsx | 3 ++- .../__snapshots__/index.test.tsx.snap | 1 + .../timeline/query_tab_content/index.test.tsx | 1 + .../timeline/query_tab_content/index.tsx | 3 ++- .../public/timelines/containers/index.tsx | 5 +++-- .../public/timelines/store/timeline/defaults.ts | 1 + .../timelines/store/timeline/epic.test.ts | 3 ++- .../store/timeline/epic_local_storage.test.tsx | 2 ++ .../timelines/store/timeline/reducer.test.ts | 6 +++++- .../lib/timeline/pick_saved_timeline.test.ts | 2 +- .../routes/__mocks__/create_timelines.ts | 2 +- .../routes/__mocks__/import_timelines.ts | 6 +++++- .../routes/__mocks__/request_responses.ts | 6 +++--- .../lib/timeline/saved_object_mappings.ts | 4 ++++ .../factory/events/all/query.events_all.dsl.ts | 11 ++++++++--- 36 files changed, 121 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/security_solution/common/search_strategy/timeline/index.ts b/x-pack/plugins/security_solution/common/search_strategy/timeline/index.ts index 6f71ed5c27516..d3ec2763f9396 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/timeline/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/timeline/index.ts @@ -28,10 +28,14 @@ export interface TimelineRequestBasicOptions extends IEsSearchRequest { factoryQueryType?: TimelineFactoryQueryTypes; } +export interface TimelineRequestSortField extends SortField { + type: string; +} + export interface TimelineRequestOptionsPaginated extends TimelineRequestBasicOptions { pagination: Pick; - sort: Array>; + sort: Array>; } export type TimelineStrategyResponseType< diff --git a/x-pack/plugins/security_solution/common/types/timeline/index.ts b/x-pack/plugins/security_solution/common/types/timeline/index.ts index 26d13b13f40cb..77d22f7120617 100644 --- a/x-pack/plugins/security_solution/common/types/timeline/index.ts +++ b/x-pack/plugins/security_solution/common/types/timeline/index.ts @@ -146,6 +146,7 @@ const SavedFavoriteRuntimeType = runtimeTypes.partial({ const SavedSortObject = runtimeTypes.partial({ columnId: unionWithNullType(runtimeTypes.string), + columnType: unionWithNullType(runtimeTypes.string), sortDirection: unionWithNullType(runtimeTypes.string), }); const SavedSortRuntimeType = runtimeTypes.union([ diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx index 6250345579cff..5e9195a686c88 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx @@ -104,6 +104,7 @@ const eventsViewerDefaultProps = { sort: [ { columnId: 'foo', + columnType: 'number', sortDirection: 'asc' as SortDirection, }, ], diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx index 1d06f07bc774b..261db75b03b33 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx @@ -216,8 +216,9 @@ const EventsViewerComponent: React.FC = ({ const sortField = useMemo( () => - sort.map(({ columnId, sortDirection }) => ({ + sort.map(({ columnId, columnType, sortDirection }) => ({ field: columnId, + type: columnType, direction: sortDirection as Direction, })), [sort] diff --git a/x-pack/plugins/security_solution/public/common/components/page/index.tsx b/x-pack/plugins/security_solution/public/common/components/page/index.tsx index 30a7685a193b2..0f1968fb3fc2d 100644 --- a/x-pack/plugins/security_solution/public/common/components/page/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/page/index.tsx @@ -26,6 +26,11 @@ SecuritySolutionAppWrapper.displayName = 'SecuritySolutionAppWrapper'; and `EuiPopover`, `EuiToolTip` global styles */ export const AppGlobalStyle = createGlobalStyle<{ theme: { eui: { euiColorPrimary: string } } }>` + // fixes double scrollbar on views with EventsTable + #kibana-body { + overflow: hidden; + } + div.app-wrapper { background-color: rgba(0,0,0,0); } diff --git a/x-pack/plugins/security_solution/public/common/mock/global_state.ts b/x-pack/plugins/security_solution/public/common/mock/global_state.ts index 320c3a0736540..9570d49fdc661 100644 --- a/x-pack/plugins/security_solution/public/common/mock/global_state.ts +++ b/x-pack/plugins/security_solution/public/common/mock/global_state.ts @@ -238,7 +238,7 @@ export const mockGlobalState: State = { pinnedEventIds: {}, pinnedEventsSaveObject: {}, itemsPerPageOptions: [5, 10, 20], - sort: [{ columnId: '@timestamp', sortDirection: Direction.desc }], + sort: [{ columnId: '@timestamp', columnType: 'number', sortDirection: Direction.desc }], isSaving: false, version: null, status: TimelineStatus.active, diff --git a/x-pack/plugins/security_solution/public/common/mock/timeline_results.ts b/x-pack/plugins/security_solution/public/common/mock/timeline_results.ts index 03109803eb9d8..3137ef4c24560 100644 --- a/x-pack/plugins/security_solution/public/common/mock/timeline_results.ts +++ b/x-pack/plugins/security_solution/public/common/mock/timeline_results.ts @@ -2150,6 +2150,7 @@ export const mockTimelineModel: TimelineModel = { sort: [ { columnId: '@timestamp', + columnType: 'number', sortDirection: Direction.desc, }, ], @@ -2184,7 +2185,7 @@ export const mockTimelineResult: TimelineResult = { templateTimelineId: null, templateTimelineVersion: null, savedQueryId: null, - sort: [{ columnId: '@timestamp', sortDirection: 'desc' }], + sort: [{ columnId: '@timestamp', columnType: 'number', sortDirection: 'desc' }], version: '1', }; @@ -2202,7 +2203,7 @@ export const defaultTimelineProps: CreateTimelineProps = { timeline: { activeTab: TimelineTabs.query, columns: [ - { columnHeaderType: 'not-filtered', id: '@timestamp', width: 190 }, + { columnHeaderType: 'not-filtered', id: '@timestamp', type: 'number', width: 190 }, { columnHeaderType: 'not-filtered', id: 'message', width: 180 }, { columnHeaderType: 'not-filtered', id: 'event.category', width: 180 }, { columnHeaderType: 'not-filtered', id: 'event.action', width: 180 }, @@ -2254,7 +2255,7 @@ export const defaultTimelineProps: CreateTimelineProps = { selectedEventIds: {}, show: false, showCheckboxes: false, - sort: [{ columnId: '@timestamp', sortDirection: Direction.desc }], + sort: [{ columnId: '@timestamp', columnType: 'number', sortDirection: Direction.desc }], status: TimelineStatus.draft, title: '', timelineType: TimelineType.default, diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx index 64e916f87b09d..bdf358dc8737b 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx @@ -111,6 +111,7 @@ describe('alert actions', () => { { columnHeaderType: 'not-filtered', id: '@timestamp', + type: 'number', width: 190, }, { @@ -207,6 +208,7 @@ describe('alert actions', () => { sort: [ { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', }, ], diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/__mocks__/index.ts b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/__mocks__/index.ts index ce4b0f09e5c95..1f6ba33157053 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/__mocks__/index.ts @@ -151,6 +151,7 @@ export const mockTimeline = { savedQueryId: null, sort: { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', __typename: 'SortTimelineResult', }, @@ -403,6 +404,7 @@ export const mockTemplate = { savedQueryId: null, sort: { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', __typename: 'SortTimelineResult', }, diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.test.ts b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.test.ts index da6eec968d11c..0e90a5ab5287a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.test.ts @@ -246,6 +246,7 @@ describe('helpers', () => { { columnHeaderType: 'not-filtered', id: '@timestamp', + type: 'number', width: 190, }, { @@ -319,6 +320,7 @@ describe('helpers', () => { sort: [ { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', }, ], @@ -347,6 +349,7 @@ describe('helpers', () => { { columnHeaderType: 'not-filtered', id: '@timestamp', + type: 'number', width: 190, }, { @@ -420,6 +423,7 @@ describe('helpers', () => { sort: [ { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', }, ], @@ -448,6 +452,7 @@ describe('helpers', () => { { columnHeaderType: 'not-filtered', id: '@timestamp', + type: 'number', width: 190, }, { @@ -521,6 +526,7 @@ describe('helpers', () => { sort: [ { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', }, ], @@ -547,6 +553,7 @@ describe('helpers', () => { { columnHeaderType: 'not-filtered', id: '@timestamp', + type: 'number', width: 190, }, { @@ -620,6 +627,7 @@ describe('helpers', () => { sort: [ { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', }, ], @@ -652,7 +660,7 @@ describe('helpers', () => { example: undefined, id: '@timestamp', placeholder: undefined, - type: undefined, + type: 'number', width: 190, }, { @@ -760,6 +768,7 @@ describe('helpers', () => { sort: [ { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', }, ], @@ -815,6 +824,7 @@ describe('helpers', () => { { columnHeaderType: 'not-filtered', id: '@timestamp', + type: 'number', width: 190, }, { @@ -929,6 +939,7 @@ describe('helpers', () => { sort: [ { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', }, ], @@ -953,6 +964,7 @@ describe('helpers', () => { { columnHeaderType: 'not-filtered', id: '@timestamp', + type: 'number', width: 190, }, { @@ -1026,6 +1038,7 @@ describe('helpers', () => { sort: [ { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', }, ], @@ -1054,6 +1067,7 @@ describe('helpers', () => { { columnHeaderType: 'not-filtered', id: '@timestamp', + type: 'number', width: 190, }, { @@ -1127,6 +1141,7 @@ describe('helpers', () => { sort: [ { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', }, ], diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/__snapshots__/index.test.tsx.snap index 36e0652c3032a..695032d80f8a0 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/__snapshots__/index.test.tsx.snap @@ -421,6 +421,7 @@ exports[`ColumnHeaders rendering renders correctly against snapshot 1`] = ` Object { "columnHeaderType": "not-filtered", "id": "@timestamp", + "type": "number", "width": 190, }, Object { @@ -468,6 +469,7 @@ exports[`ColumnHeaders rendering renders correctly against snapshot 1`] = ` Array [ Object { "columnId": "@timestamp", + "columnType": "number", "sortDirection": "desc", }, ] diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/default_headers.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/default_headers.ts index 082b5103a7d86..82cb3f2587100 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/default_headers.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/default_headers.ts @@ -13,6 +13,7 @@ export const defaultHeaders: ColumnHeaderOptions[] = [ { columnHeaderType: defaultColumnHeaderType, id: '@timestamp', + type: 'number', width: DEFAULT_DATE_COLUMN_MIN_WIDTH, }, { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/__snapshots__/index.test.tsx.snap index fa9a4e78d88f2..bd0ae9024df5b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/__snapshots__/index.test.tsx.snap @@ -7,6 +7,7 @@ exports[`Header renders correctly against snapshot 1`] = ` Object { "columnHeaderType": "not-filtered", "id": "@timestamp", + "type": "number", "width": 190, } } @@ -17,6 +18,7 @@ exports[`Header renders correctly against snapshot 1`] = ` Array [ Object { "columnId": "@timestamp", + "columnType": "number", "sortDirection": "desc", }, ] @@ -27,6 +29,7 @@ exports[`Header renders correctly against snapshot 1`] = ` Object { "columnHeaderType": "not-filtered", "id": "@timestamp", + "type": "number", "width": 190, } } @@ -36,6 +39,7 @@ exports[`Header renders correctly against snapshot 1`] = ` Array [ Object { "columnId": "@timestamp", + "columnType": "number", "sortDirection": "desc", }, ] @@ -47,6 +51,7 @@ exports[`Header renders correctly against snapshot 1`] = ` Object { "columnHeaderType": "not-filtered", "id": "@timestamp", + "type": "number", "width": 190, } } diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/index.test.tsx index 58d40c94ac338..20df1bb7a3c67 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/index.test.tsx @@ -35,6 +35,7 @@ describe('Header', () => { const sort: Sort[] = [ { columnId: columnHeader.id, + columnType: columnHeader.type ?? 'number', sortDirection: Direction.desc, }, ]; @@ -124,6 +125,7 @@ describe('Header', () => { sort: [ { columnId: columnHeader.id, + columnType: columnHeader.type ?? 'number', sortDirection: Direction.asc, // (because the previous state was Direction.desc) }, ], @@ -191,6 +193,7 @@ describe('Header', () => { const nonMatching: Sort[] = [ { columnId: 'differentSocks', + columnType: columnHeader.type ?? 'number', sortDirection: Direction.desc, }, ]; @@ -201,7 +204,11 @@ describe('Header', () => { describe('getNextSortDirection', () => { test('it returns "asc" when the current direction is "desc"', () => { - const sortDescending: Sort = { columnId: columnHeader.id, sortDirection: Direction.desc }; + const sortDescending: Sort = { + columnId: columnHeader.id, + columnType: columnHeader.type ?? 'number', + sortDirection: Direction.desc, + }; expect(getNextSortDirection(sortDescending)).toEqual('asc'); }); @@ -209,6 +216,7 @@ describe('Header', () => { test('it returns "desc" when the current direction is "asc"', () => { const sortAscending: Sort = { columnId: columnHeader.id, + columnType: columnHeader.type ?? 'number', sortDirection: Direction.asc, }; @@ -218,6 +226,7 @@ describe('Header', () => { test('it returns "desc" by default', () => { const sortNone: Sort = { columnId: columnHeader.id, + columnType: columnHeader.type ?? 'number', sortDirection: 'none', }; @@ -230,6 +239,7 @@ describe('Header', () => { const sortMatches: Sort[] = [ { columnId: columnHeader.id, + columnType: columnHeader.type ?? 'number', sortDirection: Direction.desc, }, ]; @@ -246,6 +256,7 @@ describe('Header', () => { const sortDoesNotMatch: Sort[] = [ { columnId: 'someOtherColumn', + columnType: columnHeader.type ?? 'number', sortDirection: 'none', }, ]; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/index.tsx index 192a9c6b0973b..633e7474ffa8d 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/index.tsx @@ -35,6 +35,7 @@ export const HeaderComponent: React.FC = ({ const onColumnSort = useCallback(() => { const columnId = header.id; + const columnType = header.type ?? 'text'; const sortDirection = getNewSortDirectionOnClick({ clickedHeader: header, currentSort: sort, @@ -46,6 +47,7 @@ export const HeaderComponent: React.FC = ({ ...sort, { columnId, + columnType, sortDirection, }, ]; @@ -54,6 +56,7 @@ export const HeaderComponent: React.FC = ({ ...sort.slice(0, headerIndex), { columnId, + columnType, sortDirection, }, ...sort.slice(headerIndex + 1), diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.test.tsx index 6eb279644ef3c..307166388b494 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.test.tsx @@ -38,6 +38,7 @@ describe('ColumnHeaders', () => { const sort: Sort[] = [ { columnId: '@timestamp', + columnType: 'number', sortDirection: Direction.desc, }, ]; @@ -108,10 +109,12 @@ describe('ColumnHeaders', () => { let mockSort: Sort[] = [ { columnId: '@timestamp', + columnType: 'number', sortDirection: Direction.desc, }, { columnId: 'host.name', + columnType: 'text', sortDirection: Direction.asc, }, ]; @@ -126,10 +129,12 @@ describe('ColumnHeaders', () => { mockSort = [ { columnId: '@timestamp', + columnType: 'number', sortDirection: Direction.desc, }, { columnId: 'host.name', + columnType: 'text', sortDirection: Direction.asc, }, ]; @@ -162,13 +167,15 @@ describe('ColumnHeaders', () => { sort: [ { columnId: '@timestamp', + columnType: 'number', sortDirection: Direction.desc, }, { columnId: 'host.name', + columnType: 'text', sortDirection: Direction.asc, }, - { columnId: 'event.category', sortDirection: Direction.desc }, + { columnId: 'event.category', columnType: 'text', sortDirection: Direction.desc }, ], }) ); @@ -201,9 +208,10 @@ describe('ColumnHeaders', () => { sort: [ { columnId: '@timestamp', + columnType: 'number', sortDirection: Direction.asc, }, - { columnId: 'host.name', sortDirection: Direction.asc }, + { columnId: 'host.name', columnType: 'text', sortDirection: Direction.asc }, ], }) ); @@ -236,9 +244,10 @@ describe('ColumnHeaders', () => { sort: [ { columnId: '@timestamp', + columnType: 'number', sortDirection: Direction.desc, }, - { columnId: 'host.name', sortDirection: Direction.desc }, + { columnId: 'host.name', columnType: 'text', sortDirection: Direction.desc }, ], }) ); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx index dd535094e7dc1..21f32a211f42c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx @@ -230,11 +230,12 @@ export const ColumnHeadersComponent = ({ id: timelineId, sort: cols.map(({ id, direction }) => ({ columnId: id, + columnType: columnHeaders.find((ch) => ch.id === id)?.type ?? 'text', sortDirection: direction as SortDirection, })), }) ), - [dispatch, timelineId] + [columnHeaders, dispatch, timelineId] ); const sortedColumns = useMemo( () => ({ diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx index cc04b83382998..87b475ef45974 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx @@ -22,6 +22,7 @@ import { TimelineTabs } from '../../../../../common/types/timeline'; const mockSort: Sort[] = [ { columnId: '@timestamp', + columnType: 'number', sortDirection: Direction.desc, }, ]; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/sort/index.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/sort/index.ts index 93fbe314e1dad..985c19deaa098 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/sort/index.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/sort/index.ts @@ -13,5 +13,6 @@ export type SortDirection = 'none' | Direction; /** Specifies which column the timeline is sorted on */ export interface Sort { columnId: ColumnId; + columnType: string; sortDirection: SortDirection; } diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/__snapshots__/index.test.tsx.snap index ca75dd669cafb..f5064ba66cf2f 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/__snapshots__/index.test.tsx.snap @@ -140,6 +140,7 @@ In other use cases the message field can be used to concatenate different values Array [ Object { "columnId": "@timestamp", + "columnType": "number", "sortDirection": "desc", }, ] diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/index.test.tsx index bf26dc65afcbd..89fef405bec7e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/index.test.tsx @@ -66,6 +66,7 @@ describe('PinnedTabContent', () => { const sort: Sort[] = [ { columnId: '@timestamp', + columnType: 'number', sortDirection: Direction.desc, }, ]; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/index.tsx index e204578db610c..e2eed83ec9372 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/index.tsx @@ -143,8 +143,9 @@ export const PinnedTabContentComponent: React.FC = ({ const timelineQuerySortField = useMemo( () => - sort.map(({ columnId, sortDirection }) => ({ + sort.map(({ columnId, columnType, sortDirection }) => ({ field: columnId, + type: columnType, direction: sortDirection as Direction, })), [sort] diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/__snapshots__/index.test.tsx.snap index e09a66dde6d95..4fbf7788d9122 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/__snapshots__/index.test.tsx.snap @@ -283,6 +283,7 @@ In other use cases the message field can be used to concatenate different values Array [ Object { "columnId": "@timestamp", + "columnType": "number", "sortDirection": "desc", }, ] diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx index 4f4b699f046bf..3b163a98a6a8c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx @@ -67,6 +67,7 @@ describe('Timeline', () => { const sort: Sort[] = [ { columnId: '@timestamp', + columnType: 'number', sortDirection: Direction.desc, }, ]; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.tsx index 94a67643f0025..fd9406a64404a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.tsx @@ -211,9 +211,10 @@ export const QueryTabContentComponent: React.FC = ({ const timelineQuerySortField = useMemo( () => - sort.map(({ columnId, sortDirection }) => ({ + sort.map(({ columnId, columnType, sortDirection }) => ({ field: columnId, direction: sortDirection as Direction, + type: columnType, })), [sort] ); diff --git a/x-pack/plugins/security_solution/public/timelines/containers/index.tsx b/x-pack/plugins/security_solution/public/timelines/containers/index.tsx index f9ed46171d09f..e76fe4f376804 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/containers/index.tsx @@ -26,7 +26,7 @@ import { TimelineEventsAllRequestOptions, TimelineEdges, TimelineItem, - SortField, + TimelineRequestSortField, } from '../../../common/search_strategy'; import { InspectResponse } from '../../types'; import * as i18n from './translations'; @@ -56,7 +56,7 @@ export interface UseTimelineEventsProps { fields: string[]; indexNames: string[]; limit: number; - sort: SortField[]; + sort: TimelineRequestSortField[]; startDate: string; timerangeKind?: 'absolute' | 'relative'; } @@ -69,6 +69,7 @@ export const initSortDefault = [ { field: '@timestamp', direction: Direction.asc, + type: 'number', }, ]; diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/defaults.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/defaults.ts index fd0d6bd3a9aaa..c3f5821b1eafd 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/defaults.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/defaults.ts @@ -55,6 +55,7 @@ export const timelineDefaults: SubsetTimelineModel & Pick { selectedEventIds: {}, show: true, showCheckboxes: false, - sort: [{ columnId: '@timestamp', sortDirection: Direction.desc }], + sort: [{ columnId: '@timestamp', columnType: 'number', sortDirection: Direction.desc }], status: TimelineStatus.active, version: 'WzM4LDFd', id: '11169110-fc22-11e9-8ca9-072f15ce2685', @@ -289,6 +289,7 @@ describe('Epic Timeline', () => { sort: [ { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', }, ], diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx b/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx index 513d61ea862fa..e9f39a4fcdd1f 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx @@ -61,6 +61,7 @@ describe('epicLocalStorage', () => { const sort: Sort[] = [ { columnId: '@timestamp', + columnType: 'number', sortDirection: Direction.desc, }, ]; @@ -168,6 +169,7 @@ describe('epicLocalStorage', () => { sort: [ { columnId: 'event.severity', + columnType: 'number', sortDirection: Direction.desc, }, ], diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts index 0733bf471a12c..0d7024754c8bf 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts @@ -103,6 +103,7 @@ const basicTimeline: TimelineModel = { sort: [ { columnId: '@timestamp', + columnType: 'number', sortDirection: Direction.desc, }, ], @@ -932,6 +933,7 @@ describe('Timeline', () => { sort: [ { columnId: 'some column', + columnType: 'text', sortDirection: Direction.desc, }, ], @@ -943,7 +945,9 @@ describe('Timeline', () => { }); test('should update the sort attribute', () => { - expect(update.foo.sort).toEqual([{ columnId: 'some column', sortDirection: Direction.desc }]); + expect(update.foo.sort).toEqual([ + { columnId: 'some column', columnType: 'text', sortDirection: Direction.desc }, + ]); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/pick_saved_timeline.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/pick_saved_timeline.test.ts index 92d2a9c5a3077..d9ed99972dbef 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/pick_saved_timeline.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/pick_saved_timeline.test.ts @@ -42,7 +42,7 @@ describe('pickSavedTimeline', () => { templateTimelineVersion: null, eventType: 'all', filters: [], - sort: { sortDirection: 'desc', columnId: '@timestamp' }, + sort: { sortDirection: 'desc', columnType: 'number', columnId: '@timestamp' }, title: 'title', kqlMode: 'filter', timelineType: TimelineType.default, diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/create_timelines.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/create_timelines.ts index e8242d9691032..18f080925c506 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/create_timelines.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/create_timelines.ts @@ -212,6 +212,6 @@ export const mockTimeline = { templateTimelineId: null, dateRange: { start: '2020-11-03T13:34:40.339Z', end: '2020-11-04T13:34:40.339Z' }, savedQueryId: null, - sort: { columnId: '@timestamp', sortDirection: 'desc' }, + sort: { columnId: '@timestamp', columnType: 'number', sortDirection: 'desc' }, status: 'draft', }; diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/import_timelines.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/import_timelines.ts index 90d5b538a5200..1ff7385112cae 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/import_timelines.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/import_timelines.ts @@ -23,7 +23,7 @@ export const mockParsedObjects = [ title: 'My duplicate timeline', dateRange: { start: '2020-03-18T09:31:47.294Z', end: '2020-03-19T09:31:47.294Z' }, savedQueryId: null, - sort: { columnId: '@timestamp', sortDirection: 'desc' }, + sort: { columnId: '@timestamp', columnType: 'number', sortDirection: 'desc' }, created: 1584828930463, createdBy: 'angela', updated: 1584868346013, @@ -698,6 +698,7 @@ export const mockCheckTimelinesStatusBeforeInstallResult = { savedQueryId: null, sort: { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', }, created: 1588162404153, @@ -870,6 +871,7 @@ export const mockCheckTimelinesStatusAfterInstallResult = { savedQueryId: null, sort: { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', }, timelineType: 'template', @@ -1052,6 +1054,7 @@ export const mockCheckTimelinesStatusAfterInstallResult = { savedQueryId: null, sort: { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', }, timelineType: 'template', @@ -1172,6 +1175,7 @@ export const mockCheckTimelinesStatusAfterInstallResult = { savedQueryId: null, sort: { columnId: '@timestamp', + columnType: 'number', sortDirection: 'desc', }, timelineType: 'template', diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/request_responses.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/request_responses.ts index 026ec1fa847f9..5cc2c60341090 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/request_responses.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/request_responses.ts @@ -73,7 +73,7 @@ export const inputTimeline: SavedTimeline = { templateTimelineVersion: 1, dateRange: { start: '2020-03-26T12:50:05.527Z', end: '2020-03-27T12:50:05.527Z' }, savedQueryId: null, - sort: { columnId: '@timestamp', sortDirection: 'desc' }, + sort: { columnId: '@timestamp', columnType: 'number', sortDirection: 'desc' }, }; export const inputTemplateTimeline = { @@ -289,7 +289,7 @@ export const mockTimelines = () => ({ title: 'test no.2', dateRange: { start: '2020-02-24T10:09:11.145Z', end: '2020-02-25T10:09:11.145Z' }, savedQueryId: null, - sort: { columnId: '@timestamp', sortDirection: 'desc' }, + sort: { columnId: '@timestamp', columnType: 'number', sortDirection: 'desc' }, created: 1582625382448, createdBy: 'elastic', updated: 1583741197521, @@ -371,7 +371,7 @@ export const mockTimelines = () => ({ title: 'test no.3', dateRange: { start: '2020-02-24T10:09:11.145Z', end: '2020-02-25T10:09:11.145Z' }, savedQueryId: null, - sort: { columnId: '@timestamp', sortDirection: 'desc' }, + sort: { columnId: '@timestamp', columnType: 'number', sortDirection: 'desc' }, created: 1582642817439, createdBy: 'elastic', updated: 1583741175216, diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings.ts index 11082cd7295cc..dc7565daf0b00 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings.ts @@ -266,10 +266,14 @@ export const timelineSavedObjectMappings: SavedObjectsType['mappings'] = { type: 'keyword', }, sort: { + dynamic: false, properties: { columnId: { type: 'keyword', }, + columnType: { + type: 'keyword', + }, sortDirection: { type: 'keyword', }, diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/query.events_all.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/query.events_all.dsl.ts index 3ff542ebde5fe..a5cfc86c7d5c3 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/query.events_all.dsl.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/query.events_all.dsl.ts @@ -6,10 +6,10 @@ import { isEmpty } from 'lodash/fp'; import { - SortField, TimerangeFilter, TimerangeInput, TimelineEventsAllRequestOptions, + TimelineRequestSortField, } from '../../../../../../common/search_strategy'; import { createQueryFilterClauses } from '../../../../../utils/build_query'; @@ -46,10 +46,15 @@ export const buildTimelineEventsAllQuery = ({ const filter = [...filterClause, ...getTimerangeFilter(timerange), { match_all: {} }]; - const getSortField = (sortFields: SortField[]) => + const getSortField = (sortFields: TimelineRequestSortField[]) => sortFields.map((item) => { const field: string = item.field === 'timestamp' ? '@timestamp' : item.field; - return { [field]: item.direction }; + return { + [field]: { + order: item.direction, + unmapped_type: item.type, + }, + }; }); const dslQuery = { From ddf1b67559a7e675386d0a3d75e8210b7187600f Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Mon, 11 Jan 2021 16:18:01 -0700 Subject: [PATCH 22/64] [Maps] move map embeddable display properties to map settings (#86395) * [Maps] move map embeddable display properties to map settings * update uptime EmbeddedMap * tslint * more cleanup Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../public/actions/map_action_constants.ts | 5 - .../maps/public/actions/map_actions.ts | 26 +--- .../map_container/index.ts | 4 +- .../map_container/map_container.tsx | 8 +- .../connected_components/mb_map/index.ts | 6 - .../connected_components/mb_map/mb_map.tsx | 11 +- .../widget_overlay/index.js | 5 +- .../widget_overlay/widget_overlay.js | 6 +- .../plugins/maps/public/embeddable/README.md | 143 ------------------ .../maps/public/embeddable/map_embeddable.tsx | 24 --- .../plugins/maps/public/embeddable/types.ts | 7 +- .../public/reducers/default_map_settings.ts | 5 + x-pack/plugins/maps/public/reducers/map.d.ts | 10 +- x-pack/plugins/maps/public/reducers/map.js | 50 ------ .../routes/map_page/saved_map/saved_map.ts | 4 +- .../maps/public/selectors/map_selectors.ts | 15 -- .../location_map/embeddables/embedded_map.tsx | 10 +- 17 files changed, 36 insertions(+), 303 deletions(-) delete mode 100644 x-pack/plugins/maps/public/embeddable/README.md diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index 25a86e4c50d07..3e5b9677b003a 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -38,11 +38,6 @@ export const SET_OPEN_TOOLTIPS = 'SET_OPEN_TOOLTIPS'; export const UPDATE_DRAW_STATE = 'UPDATE_DRAW_STATE'; export const SET_SCROLL_ZOOM = 'SET_SCROLL_ZOOM'; export const SET_MAP_INIT_ERROR = 'SET_MAP_INIT_ERROR'; -export const SET_INTERACTIVE = 'SET_INTERACTIVE'; -export const DISABLE_TOOLTIP_CONTROL = 'DISABLE_TOOLTIP_CONTROL'; -export const HIDE_TOOLBAR_OVERLAY = 'HIDE_TOOLBAR_OVERLAY'; -export const HIDE_LAYER_CONTROL = 'HIDE_LAYER_CONTROL'; -export const HIDE_VIEW_CONTROL = 'HIDE_VIEW_CONTROL'; export const SET_WAITING_FOR_READY_HIDDEN_LAYERS = 'SET_WAITING_FOR_READY_HIDDEN_LAYERS'; export const SET_MAP_SETTINGS = 'SET_MAP_SETTINGS'; export const ROLLBACK_MAP_SETTINGS = 'ROLLBACK_MAP_SETTINGS'; diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 6dd8db4799d47..64c35bd207439 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -24,16 +24,11 @@ import { CLEAR_GOTO, CLEAR_MOUSE_COORDINATES, CLEAR_WAITING_FOR_MAP_READY_LAYER_LIST, - DISABLE_TOOLTIP_CONTROL, - HIDE_LAYER_CONTROL, - HIDE_TOOLBAR_OVERLAY, - HIDE_VIEW_CONTROL, MAP_DESTROYED, MAP_EXTENT_CHANGED, MAP_READY, ROLLBACK_MAP_SETTINGS, SET_GOTO, - SET_INTERACTIVE, SET_MAP_INIT_ERROR, SET_MAP_SETTINGS, SET_MOUSE_COORDINATES, @@ -73,7 +68,7 @@ export function setMapInitError(errorMessage: string) { }; } -export function setMapSettings(settings: MapSettings) { +export function setMapSettings(settings: Partial) { return { type: SET_MAP_SETTINGS, settings, @@ -316,22 +311,3 @@ export function updateDrawState(drawState: DrawState | null) { }); }; } - -export function disableInteractive() { - return { type: SET_INTERACTIVE, disableInteractive: true }; -} - -export function disableTooltipControl() { - return { type: DISABLE_TOOLTIP_CONTROL, disableTooltipControl: true }; -} - -export function hideToolbarOverlay() { - return { type: HIDE_TOOLBAR_OVERLAY, hideToolbarOverlay: true }; -} - -export function hideLayerControl() { - return { type: HIDE_LAYER_CONTROL, hideLayerControl: true }; -} -export function hideViewControl() { - return { type: HIDE_VIEW_CONTROL, hideViewControl: true }; -} diff --git a/x-pack/plugins/maps/public/connected_components/map_container/index.ts b/x-pack/plugins/maps/public/connected_components/map_container/index.ts index 37ee3a630066d..e4c5cfe1c63a9 100644 --- a/x-pack/plugins/maps/public/connected_components/map_container/index.ts +++ b/x-pack/plugins/maps/public/connected_components/map_container/index.ts @@ -16,7 +16,6 @@ import { getMapInitError, getMapSettings, getQueryableUniqueIndexPatternIds, - isToolbarOverlayHidden, } from '../../selectors/map_selectors'; import { MapStoreState } from '../../reducers/store'; import { getCoreChrome } from '../../kibana_services'; @@ -29,8 +28,7 @@ function mapStateToProps(state: MapStoreState) { refreshConfig: getRefreshConfig(state), mapInitError: getMapInitError(state), indexPatternIds: getQueryableUniqueIndexPatternIds(state), - hideToolbarOverlay: isToolbarOverlayHidden(state), - backgroundColor: getMapSettings(state).backgroundColor, + settings: getMapSettings(state), }; } diff --git a/x-pack/plugins/maps/public/connected_components/map_container/map_container.tsx b/x-pack/plugins/maps/public/connected_components/map_container/map_container.tsx index d7881d5f84bd1..93476f6e14da5 100644 --- a/x-pack/plugins/maps/public/connected_components/map_container/map_container.tsx +++ b/x-pack/plugins/maps/public/connected_components/map_container/map_container.tsx @@ -25,6 +25,7 @@ import { getIndexPatternsFromIds } from '../../index_pattern_util'; import { ES_GEO_FIELD_TYPE, RawValue } from '../../../common/constants'; import { indexPatterns as indexPatternsUtils } from '../../../../../../src/plugins/data/public'; import { FLYOUT_STATE } from '../../reducers/ui'; +import { MapSettings } from '../../reducers/map'; import { MapSettingsPanel } from '../map_settings_panel'; import { registerLayerWizards } from '../../classes/layers/load_layer_wizards'; import { RenderToolTipContent } from '../../classes/tooltips/tooltip_property'; @@ -36,7 +37,6 @@ const RENDER_COMPLETE_EVENT = 'renderComplete'; interface Props { addFilters: ((filters: Filter[]) => Promise) | null; - backgroundColor: string; getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; onSingleValueTrigger?: (actionId: string, key: string, value: RawValue) => void; @@ -44,7 +44,6 @@ interface Props { cancelAllInFlightRequests: () => void; exitFullScreen: () => void; flyoutDisplay: FLYOUT_STATE; - hideToolbarOverlay: boolean; isFullScreen: boolean; indexPatternIds: string[]; mapInitError: string | null | undefined; @@ -53,6 +52,7 @@ interface Props { triggerRefreshTimer: () => void; title?: string; description?: string; + settings: MapSettings; } interface State { @@ -245,7 +245,7 @@ export class MapContainer extends Component { > { geoFields={this.state.geoFields} renderTooltipContent={renderTooltipContent} /> - {!this.props.hideToolbarOverlay && ( + {!this.props.settings.hideToolbarOverlay && ( void; onMapReady: (mapExtentState: MapExtentState) => void; onMapDestroyed: () => void; @@ -181,7 +178,7 @@ export class MBMap extends Component { style: mbStyle, scrollZoom: this.props.scrollZoom, preserveDrawingBuffer: getPreserveDrawingBuffer(), - interactive: !this.props.disableInteractive, + interactive: !this.props.settings.disableInteractive, maxZoom: this.props.settings.maxZoom, minZoom: this.props.settings.minZoom, }; @@ -197,7 +194,7 @@ export class MBMap extends Component { const mbMap = new mapboxgl.Map(options); mbMap.dragRotate.disable(); mbMap.touchZoomRotate.disableRotation(); - if (!this.props.disableInteractive) { + if (!this.props.settings.disableInteractive) { mbMap.addControl(new mapboxgl.NavigationControl({ showCompass: false }), 'top-left'); } @@ -260,7 +257,7 @@ export class MBMap extends Component { }, 100) ); // Attach event only if view control is visible, which shows lat/lon - if (!this.props.hideViewControl) { + if (!this.props.settings.hideViewControl) { const throttledSetMouseCoordinates = _.throttle((e: MapMouseEvent) => { this.props.setMouseCoordinates({ lat: e.lngLat.lat, @@ -386,7 +383,7 @@ export class MBMap extends Component { let tooltipControl; if (this.state.mbMap) { drawControl = ; - tooltipControl = !this.props.disableTooltipControl ? ( + tooltipControl = !this.props.settings.disableTooltipControl ? ( - {!hideLayerControl && } + {!settings.hideLayerControl && } - {!hideViewControl && } + {!settings.hideViewControl && } diff --git a/x-pack/plugins/maps/public/embeddable/README.md b/x-pack/plugins/maps/public/embeddable/README.md deleted file mode 100644 index 8ce3794e2ed2c..0000000000000 --- a/x-pack/plugins/maps/public/embeddable/README.md +++ /dev/null @@ -1,143 +0,0 @@ - -### Map specific `input` parameters -- **hideFilterActions:** (Boolean) Set to true to hide all filtering controls. -- **isLayerTOCOpen:** (Boolean) Set to false to render map with legend in collapsed state. -- **openTOCDetails:** (Array of Strings) Array of layer ids. Add layer id to show layer details on initial render. -- **mapCenter:** ({lat, lon, zoom }) Provide mapCenter to customize initial map location. -- **disableInteractive:** (Boolean) Will disable map interactions, panning, zooming in the map. -- **disableTooltipControl:** (Boolean) Will disable tooltip which shows relevant information on hover, like Continent name etc -- **hideToolbarOverlay:** (Boolean) Will disable toolbar, which can be used to navigate to coordinate by entering lat/long and zoom values. -- **hideLayerControl:** (Boolean) Will hide useful layer control, which can be used to hide/show a layer to get a refined view of the map. -- **hideViewControl:** (Boolean) Will hide view control at bottom right of the map, which shows lat/lon values based on mouse hover in the map, this is useful to get coordinate value from a particular point in map. -- **hiddenLayers:** (Array of Strings) Array of layer ids that should be hidden. Any other layers will be set to visible regardless of their value in the layerList used to initialize the embeddable - -### Creating a Map embeddable from saved object -``` - const factory = new MapEmbeddableFactory(); - const input = { - hideFilterActions: true, - isLayerTOCOpen: false, - openTOCDetails: ['tfi3f', 'edh66'], - mapCenter: { lat: 0.0, lon: 0.0, zoom: 7 } - } - const mapEmbeddable = await factory.createFromSavedObject( - 'de71f4f0-1902-11e9-919b-ffe5949a18d2', - input, - parent - ); -``` - -### Creating a Map embeddable from state -``` -const factory = new MapEmbeddableFactory(); -const input = { - hideFilterActions: true, - isLayerTOCOpen: false, - openTOCDetails: ['tfi3f', 'edh66'], - mapCenter: { lat: 0.0, lon: 0.0, zoom: 7 } -} -const mapEmbeddable = await factory.create(input, parent); -// where layerList is same as saved object layerListJSON property (unstringified)) -mapEmbeddable.setLayerList([]); -``` - -#### Customize tooltip -``` -/** - * Render custom tooltip content - * - * @param {function} addFilters - * @param {function} closeTooltip - * @param {Array} features - Vector features at tooltip location. - * @param {boolean} isLocked - * @param {function} getLayerName - Get layer name. Call with (layerId). Returns Promise. - * @param {function} loadFeatureProperties - Loads feature properties. Call with ({ layerId, featureId }). Returns Promise. - * @param {function} loadFeatureGeometry - Loads feature geometry. Call with ({ layerId, featureId }). Returns geojson geometry object { type, coordinates }. - * - * @return {Component} A React Component. - */ -const renderTooltipContent = ({ addFilters, closeTooltip, features, isLocked, loadFeatureProperties}) => { - return
Custom tooltip content
; -} - -const mapEmbeddable = await factory.create(input, parent) -mapEmbeddable.setLayerList(layerList); -mapEmbeddable.setRenderTooltipContent(renderTooltipContent); -``` - - -#### Event handlers -``` -const eventHandlers = { - onDataLoad: (layerId: string, dataId: string) => { - // take action on data load - }, - onDataLoadEnd: (layerId: string, dataId: string, resultMeta: object) => { - // take action on data load end - }, - onDataLoadError: (layerId: string, dataId: string, errorMessage: string) => { - // take action on data load error - }, -} - -const mapEmbeddable = await factory.create(input, parent); -mapEmbeddable.setLayerList(layerList); -mapEmbeddable.setRenderTooltipContent(renderTooltipContent); -mapEmbeddable.setEventHandlers(eventHandlers); -``` - - -#### Passing in geospatial data -You can pass geospatial data into the Map embeddable by configuring the layerList parameter with a layer with `GEOJSON_FILE` source. -Geojson sources will not update unless you modify `__featureCollection` property by calling the `setLayerList` method. - -``` -const factory = new MapEmbeddableFactory(); -const input = { - hideFilterActions: true, - isLayerTOCOpen: false, - openTOCDetails: ['tfi3f', 'edh66'], - mapCenter: { lat: 0.0, lon: 0.0, zoom: 7 } -} -const mapEmbeddable = await factory.create(input, parent); - -mapEmbeddable.setLayerList([ - { - 'id': 'gaxya', - 'label': 'My geospatial data', - 'minZoom': 0, - 'maxZoom': 24, - 'alpha': 1, - 'sourceDescriptor': { - 'id': 'b7486', - 'type': 'GEOJSON_FILE', - '__featureCollection': { - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [35, 35], [45, 45], [45, 35], [35, 35] - ] - ] - }, - "properties": { - "name": "null island", - "another_prop": "something else interesting" - } - } - ] - } - }, - 'visible': true, - 'style': { - 'type': 'VECTOR', - 'properties': {} - }, - 'type': 'VECTOR' - } -]); -``` diff --git a/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx b/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx index 5448043b35ba8..5b9aea75b1a2d 100644 --- a/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx +++ b/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx @@ -31,11 +31,6 @@ import { setQuery, setRefreshConfig, disableScrollZoom, - disableInteractive, - disableTooltipControl, - hideToolbarOverlay, - hideLayerControl, - hideViewControl, setReadOnly, } from '../actions'; import { getIsLayerTOCOpen, getOpenTOCDetails } from '../selectors/ui_selectors'; @@ -129,25 +124,6 @@ export class MapEmbeddable store.dispatch(setReadOnly(true)); store.dispatch(disableScrollZoom()); - if (_.has(this.input, 'disableInteractive') && this.input.disableInteractive) { - store.dispatch(disableInteractive()); - } - - if (_.has(this.input, 'disableTooltipControl') && this.input.disableTooltipControl) { - store.dispatch(disableTooltipControl()); - } - if (_.has(this.input, 'hideToolbarOverlay') && this.input.hideToolbarOverlay) { - store.dispatch(hideToolbarOverlay()); - } - - if (_.has(this.input, 'hideLayerControl') && this.input.hideLayerControl) { - store.dispatch(hideLayerControl()); - } - - if (_.has(this.input, 'hideViewControl') && this.input.hideViewControl) { - store.dispatch(hideViewControl()); - } - this._dispatchSetQuery({ query: this.input.query, timeRange: this.input.timeRange, diff --git a/x-pack/plugins/maps/public/embeddable/types.ts b/x-pack/plugins/maps/public/embeddable/types.ts index 417991ea2d367..40fdbd3166827 100644 --- a/x-pack/plugins/maps/public/embeddable/types.ts +++ b/x-pack/plugins/maps/public/embeddable/types.ts @@ -13,6 +13,7 @@ import { import { RefreshInterval, Query, Filter, TimeRange } from '../../../../../src/plugins/data/common'; import { MapCenterAndZoom } from '../../common/descriptor_types'; import { MapSavedObjectAttributes } from '../../common/map_saved_object_type'; +import { MapSettings } from '../reducers/map'; export interface MapEmbeddableConfig { editable: boolean; @@ -22,12 +23,8 @@ interface MapEmbeddableState { refreshConfig?: RefreshInterval; isLayerTOCOpen?: boolean; openTOCDetails?: string[]; - disableTooltipControl?: boolean; - disableInteractive?: boolean; - hideToolbarOverlay?: boolean; - hideLayerControl?: boolean; - hideViewControl?: boolean; mapCenter?: MapCenterAndZoom; + mapSettings?: Partial; hiddenLayers?: string[]; hideFilterActions?: boolean; filters?: Filter[]; diff --git a/x-pack/plugins/maps/public/reducers/default_map_settings.ts b/x-pack/plugins/maps/public/reducers/default_map_settings.ts index e98af6f426b5a..37fd19ea5a477 100644 --- a/x-pack/plugins/maps/public/reducers/default_map_settings.ts +++ b/x-pack/plugins/maps/public/reducers/default_map_settings.ts @@ -12,6 +12,11 @@ export function getDefaultMapSettings(): MapSettings { return { autoFitToDataBounds: false, backgroundColor: euiThemeVars.euiColorEmptyShade, + disableInteractive: false, + disableTooltipControl: false, + hideToolbarOverlay: false, + hideLayerControl: false, + hideViewControl: false, initialLocation: INITIAL_LOCATION.LAST_SAVED_LOCATION, fixedLocation: { lat: 0, lon: 0, zoom: 2 }, browserLocation: { zoom: 2 }, diff --git a/x-pack/plugins/maps/public/reducers/map.d.ts b/x-pack/plugins/maps/public/reducers/map.d.ts index d4ac20c7114dc..da185a190e6dc 100644 --- a/x-pack/plugins/maps/public/reducers/map.d.ts +++ b/x-pack/plugins/maps/public/reducers/map.d.ts @@ -34,16 +34,16 @@ export type MapContext = { refreshConfig?: MapRefreshConfig; refreshTimerLastTriggeredAt?: string; drawState?: DrawState; - disableInteractive: boolean; - disableTooltipControl: boolean; - hideToolbarOverlay: boolean; - hideLayerControl: boolean; - hideViewControl: boolean; }; export type MapSettings = { autoFitToDataBounds: boolean; backgroundColor: string; + disableInteractive: boolean; + disableTooltipControl: boolean; + hideToolbarOverlay: boolean; + hideLayerControl: boolean; + hideViewControl: boolean; initialLocation: INITIAL_LOCATION; fixedLocation: { lat: number; diff --git a/x-pack/plugins/maps/public/reducers/map.js b/x-pack/plugins/maps/public/reducers/map.js index 317c11eb7680c..1395f2c5ce2fe 100644 --- a/x-pack/plugins/maps/public/reducers/map.js +++ b/x-pack/plugins/maps/public/reducers/map.js @@ -39,11 +39,6 @@ import { SET_SCROLL_ZOOM, SET_MAP_INIT_ERROR, UPDATE_DRAW_STATE, - SET_INTERACTIVE, - DISABLE_TOOLTIP_CONTROL, - HIDE_TOOLBAR_OVERLAY, - HIDE_LAYER_CONTROL, - HIDE_VIEW_CONTROL, SET_WAITING_FOR_READY_HIDDEN_LAYERS, SET_MAP_SETTINGS, ROLLBACK_MAP_SETTINGS, @@ -118,11 +113,6 @@ export const DEFAULT_MAP_STATE = { refreshConfig: null, refreshTimerLastTriggeredAt: null, drawState: null, - disableInteractive: false, - disableTooltipControl: false, - hideToolbarOverlay: false, - hideLayerControl: false, - hideViewControl: false, }, selectedLayerId: null, layerList: [], @@ -355,46 +345,6 @@ export function map(state = DEFAULT_MAP_STATE, action) { ...state, mapInitError: action.errorMessage, }; - case SET_INTERACTIVE: - return { - ...state, - mapState: { - ...state.mapState, - disableInteractive: action.disableInteractive, - }, - }; - case DISABLE_TOOLTIP_CONTROL: - return { - ...state, - mapState: { - ...state.mapState, - disableTooltipControl: action.disableTooltipControl, - }, - }; - case HIDE_TOOLBAR_OVERLAY: - return { - ...state, - mapState: { - ...state.mapState, - hideToolbarOverlay: action.hideToolbarOverlay, - }, - }; - case HIDE_LAYER_CONTROL: - return { - ...state, - mapState: { - ...state.mapState, - hideLayerControl: action.hideLayerControl, - }, - }; - case HIDE_VIEW_CONTROL: - return { - ...state, - mapState: { - ...state.mapState, - hideViewControl: action.hideViewControl, - }, - }; case SET_WAITING_FOR_READY_HIDDEN_LAYERS: return { ...state, diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts b/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts index 3530e3cc615ad..88516aadc339a 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts @@ -102,7 +102,9 @@ export class SavedMap { } } - if (this._attributes?.mapStateJSON) { + if (this._mapEmbeddableInput && this._mapEmbeddableInput.mapSettings !== undefined) { + this._store.dispatch(setMapSettings(this._mapEmbeddableInput.mapSettings)); + } else if (this._attributes?.mapStateJSON) { const mapState = JSON.parse(this._attributes.mapStateJSON); if (mapState.settings) { this._store.dispatch(setMapSettings(mapState.settings)); diff --git a/x-pack/plugins/maps/public/selectors/map_selectors.ts b/x-pack/plugins/maps/public/selectors/map_selectors.ts index 9a1b31852d39c..0a18f7aca8dd1 100644 --- a/x-pack/plugins/maps/public/selectors/map_selectors.ts +++ b/x-pack/plugins/maps/public/selectors/map_selectors.ts @@ -150,21 +150,6 @@ export const getWaitingForMapReadyLayerListRaw = ({ map }: MapStoreState): Layer export const getScrollZoom = ({ map }: MapStoreState): boolean => map.mapState.scrollZoom; -export const isInteractiveDisabled = ({ map }: MapStoreState): boolean => - map.mapState.disableInteractive; - -export const isTooltipControlDisabled = ({ map }: MapStoreState): boolean => - map.mapState.disableTooltipControl; - -export const isToolbarOverlayHidden = ({ map }: MapStoreState): boolean => - map.mapState.hideToolbarOverlay; - -export const isLayerControlHidden = ({ map }: MapStoreState): boolean => - map.mapState.hideLayerControl; - -export const isViewControlHidden = ({ map }: MapStoreState): boolean => - map.mapState.hideViewControl; - export const getMapExtent = ({ map }: MapStoreState): MapExtent | undefined => map.mapState.extent; export const getMapBuffer = ({ map }: MapStoreState): MapExtent | undefined => map.mapState.buffer; diff --git a/x-pack/plugins/uptime/public/components/monitor/status_details/location_map/embeddables/embedded_map.tsx b/x-pack/plugins/uptime/public/components/monitor/status_details/location_map/embeddables/embedded_map.tsx index 2da57ef3138c7..3cab8fb562ceb 100644 --- a/x-pack/plugins/uptime/public/components/monitor/status_details/location_map/embeddables/embedded_map.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/status_details/location_map/embeddables/embedded_map.tsx @@ -83,10 +83,12 @@ export const EmbeddedMap = React.memo(({ upPoints, downPoints }: EmbeddedMapProp lat: 20, zoom: 0, }, - disableInteractive: true, - hideToolbarOverlay: true, - hideLayerControl: true, - hideViewControl: true, + mapSettings: { + disableInteractive: true, + hideToolbarOverlay: true, + hideLayerControl: true, + hideViewControl: true, + }, }; const renderTooltipContent = ({ From f54f155305deede012cf708b3ae9f133677d853a Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Mon, 11 Jan 2021 18:36:39 -0600 Subject: [PATCH 23/64] [Metrics UI] Add APM, uptime and create alert links to overlay (#87883) * Add APM, uptime and create alert links to overlay * Remove unused i18n --- .../inventory/components/alert_flyout.tsx | 2 +- .../components/node_details/overlay.tsx | 48 ++++++++++++++++--- .../inventory_view/components/waffle/node.tsx | 30 +++++++++++- .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 5 files changed, 72 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/infra/public/alerting/inventory/components/alert_flyout.tsx b/x-pack/plugins/infra/public/alerting/inventory/components/alert_flyout.tsx index 1c6852c5eb8d9..7da98283b7cc1 100644 --- a/x-pack/plugins/infra/public/alerting/inventory/components/alert_flyout.tsx +++ b/x-pack/plugins/infra/public/alerting/inventory/components/alert_flyout.tsx @@ -18,7 +18,7 @@ interface Props { options?: Partial; nodeType?: InventoryItemType; filter?: string; - setVisible: React.Dispatch>; + setVisible(val: boolean): void; } export const AlertFlyout = ({ options, nodeType, filter, visible, setVisible }: Props) => { diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx index 4541a55dbeca7..661844a627a58 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx @@ -9,6 +9,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import React, { useMemo, useState } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiButtonEmpty } from '@elastic/eui'; import { EuiOutsideClickDetector } from '@elastic/eui'; +import { EuiIcon, EuiButtonIcon } from '@elastic/eui'; import { euiStyled } from '../../../../../../../observability/public'; import { InfraWaffleMapNode, InfraWaffleMapOptions } from '../../../../../lib/lib'; import { InventoryItemType } from '../../../../../../common/inventory_models/types'; @@ -20,6 +21,7 @@ import { OVERLAY_Y_START, OVERLAY_BOTTOM_MARGIN } from './tabs/shared'; import { useLinkProps } from '../../../../../hooks/use_link_props'; import { getNodeDetailUrl } from '../../../../link_to'; import { findInventoryModel } from '../../../../../../common/inventory_models'; +import { createUptimeLink } from '../../lib/create_uptime_link'; interface Props { isOpen: boolean; @@ -28,6 +30,7 @@ interface Props { currentTime: number; node: InfraWaffleMapNode; nodeType: InventoryItemType; + openAlertFlyout(): void; } export const NodeContextPopover = ({ isOpen, @@ -36,6 +39,7 @@ export const NodeContextPopover = ({ currentTime, options, onClose, + openAlertFlyout, }: Props) => { // eslint-disable-next-line react-hooks/exhaustive-deps const tabConfigs = [MetricsTab, LogsTab, ProcessesTab, PropertiesTab]; @@ -64,6 +68,15 @@ export const NodeContextPopover = ({ to: currentTime, }), }); + const apmField = nodeType === 'host' ? 'host.hostname' : inventoryModel.fields.id; + const apmTracesMenuItemLinkProps = useLinkProps({ + app: 'apm', + hash: 'traces', + search: { + kuery: `${apmField}:"${node.id}"`, + }, + }); + const uptimeMenuItemLinkProps = useLinkProps(createUptimeLink(options, nodeType, node)); if (!isOpen) { return null; @@ -82,6 +95,20 @@ export const NodeContextPopover = ({
+ + + + + - - - + @@ -118,6 +140,20 @@ export const NodeContextPopover = ({ {tab.name} ))} + + {' '} + + + + {' '} + + {tabs[selectedTab].content} diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node.tsx index bf4682e65815c..4024f6b505c29 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node.tsx @@ -22,10 +22,13 @@ import { InventoryItemType } from '../../../../../../common/inventory_models/typ import { NodeContextPopover } from '../node_details/overlay'; import { NodeContextMenu } from './node_context_menu'; +import { AlertFlyout } from '../../../../../alerting/inventory/components/alert_flyout'; +import { findInventoryFields } from '../../../../../../common/inventory_models'; const initialState = { isPopoverOpen: false, isOverlayOpen: false, + isAlertFlyoutVisible: false, }; type State = Readonly; @@ -44,7 +47,7 @@ export const Node = class extends React.PureComponent { public readonly state: State = initialState; public render() { const { nodeType, node, options, squareSize, bounds, formatter, currentTime } = this.props; - const { isPopoverOpen } = this.state; + const { isPopoverOpen, isAlertFlyoutVisible } = this.state; const metric = first(node.metrics); const valueMode = squareSize > 70; const ellipsisMode = squareSize > 30; @@ -103,6 +106,7 @@ export const Node = class extends React.PureComponent { { currentTime={currentTime} onClose={this.toggleNewOverlay} /> + ); } + private openAlertFlyout = () => { + this.setState({ + isOverlayOpen: false, + isAlertFlyoutVisible: true, + }); + }; + + private setAlertFlyoutVisible = (isOpen: boolean) => { + this.setState({ + isAlertFlyoutVisible: isOpen, + }); + }; + private togglePopover = () => { const { nodeType } = this.props; if (nodeType === 'host') { diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index de1e26580d87f..c6ba63ece55c8 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -9853,7 +9853,6 @@ "xpack.infra.homePage.settingsTabTitle": "設定", "xpack.infra.homePage.toolbar.kqlSearchFieldPlaceholder": "インフラストラクチャーデータを検索… (例: host.name:host-1)", "xpack.infra.homePage.toolbar.showingLastOneMinuteDataText": "指定期間のデータの最後の{duration}", - "xpack.infra.infra.nodeDetails.close": "閉じる", "xpack.infra.infra.nodeDetails.openAsPage": "ページとして開く", "xpack.infra.infrastructureMetricsExplorerPage.documentTitle": "{previousTitle} | メトリックエクスプローラー", "xpack.infra.infrastructureSnapshotPage.documentTitle": "{previousTitle} | インベントリ", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 7169197a7628e..23842498457c5 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -9879,7 +9879,6 @@ "xpack.infra.homePage.settingsTabTitle": "设置", "xpack.infra.homePage.toolbar.kqlSearchFieldPlaceholder": "搜索基础设施数据……(例如 host.name:host-1)", "xpack.infra.homePage.toolbar.showingLastOneMinuteDataText": "选定时间过去 {duration}的数据", - "xpack.infra.infra.nodeDetails.close": "关闭", "xpack.infra.infra.nodeDetails.openAsPage": "以页面形式打开", "xpack.infra.infrastructureMetricsExplorerPage.documentTitle": "{previousTitle} | 指标浏览器", "xpack.infra.infrastructureSnapshotPage.documentTitle": "{previousTitle} | 库存", From ca31bd80b6a2971dcfd1073aac628f3511c5d218 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 11 Jan 2021 20:02:23 -0500 Subject: [PATCH 24/64] [Uptime] Tests/uptime testing utils (#87650) * add additional component test helpers * add test examples * uptime testing utils remove custom prefix from props and parameter options * skip executed step tests * adjust MlJobLink test * add testing util interfaces * update mock core * combine wrappers into one custom render function * split enzyme helpers and rtl helpers into different files and adjust types * adjust types * spread core on render function * remove unnecessary items from MLJobLink test * update use_monitor_breadcrumbs test Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../__snapshots__/ml_job_link.test.tsx.snap | 117 ------------------ .../monitor/ml/ml_job_link.test.tsx | 28 ++--- .../monitor/synthetics/executed_step.test.tsx | 30 +---- .../use_monitor_breadcrumbs.test.tsx | 64 +++++----- .../public/lib/__mocks__/uptime_store.mock.ts | 6 +- ...per_with_router.tsx => enzyme_helpers.tsx} | 5 +- .../public/lib/helper/helper_with_redux.tsx | 4 +- .../uptime/public/lib/helper/rtl_helpers.tsx | 109 ++++++++++++++++ x-pack/plugins/uptime/public/lib/index.ts | 2 +- 9 files changed, 162 insertions(+), 203 deletions(-) delete mode 100644 x-pack/plugins/uptime/public/components/monitor/ml/__snapshots__/ml_job_link.test.tsx.snap rename x-pack/plugins/uptime/public/lib/helper/{helper_with_router.tsx => enzyme_helpers.tsx} (97%) create mode 100644 x-pack/plugins/uptime/public/lib/helper/rtl_helpers.tsx diff --git a/x-pack/plugins/uptime/public/components/monitor/ml/__snapshots__/ml_job_link.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/ml/__snapshots__/ml_job_link.test.tsx.snap deleted file mode 100644 index aaabf0551cff6..0000000000000 --- a/x-pack/plugins/uptime/public/components/monitor/ml/__snapshots__/ml_job_link.test.tsx.snap +++ /dev/null @@ -1,117 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ML JobLink renders without errors 1`] = ` - - - - - -`; - -exports[`ML JobLink shallow renders without errors 1`] = ` - - - - - -`; diff --git a/x-pack/plugins/uptime/public/components/monitor/ml/ml_job_link.test.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/ml_job_link.test.tsx index 18cab0fea55d9..74e07879f30dc 100644 --- a/x-pack/plugins/uptime/public/components/monitor/ml/ml_job_link.test.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/ml/ml_job_link.test.tsx @@ -5,28 +5,20 @@ */ import React from 'react'; -import { coreMock } from 'src/core/public/mocks'; -import { renderWithRouter, shallowWithRouter } from '../../../lib'; +import { render } from '../../../lib/helper/rtl_helpers'; import { MLJobLink } from './ml_job_link'; -import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public'; -const core = coreMock.createStart(); describe('ML JobLink', () => { - it('shallow renders without errors', () => { - const wrapper = shallowWithRouter( - - ); - expect(wrapper).toMatchSnapshot(); - }); - it('renders without errors', () => { - const wrapper = renderWithRouter( - - - + const expectedHref = `/app/ml#/explorer?_g=(ml:(jobIds:!(testmonitor_high_latency_by_geo)),refreshInterval:(pause:!t,value:0),time:(from:'',to:''))&_a=(mlExplorerFilter:(filterActive:!t,filteredFields:!(monitor.id,testMonitor)),mlExplorerSwimlane:(viewByFieldName:observer.geo.name))`; + const { getByRole, getByText } = render( + +
Test link
+
); - expect(wrapper).toMatchSnapshot(); + + const jobLink = getByRole('link'); + expect(jobLink.getAttribute('href')).toBe(expectedHref); + expect(getByText('Test link')); }); }); diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/executed_step.test.tsx b/x-pack/plugins/uptime/public/components/monitor/synthetics/executed_step.test.tsx index 45f91ee8a6ae5..5f40b60420f83 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/executed_step.test.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/executed_step.test.tsx @@ -8,6 +8,7 @@ import React from 'react'; import { ExecutedStep } from './executed_step'; import { Ping } from '../../../../common/runtime_types'; import { mountWithRouter } from '../../../lib'; +import { render } from '../../../lib/helper/rtl_helpers'; // FLAKY: https://github.com/elastic/kibana/issues/85899 describe.skip('ExecutedStep', () => { @@ -35,32 +36,9 @@ describe.skip('ExecutedStep', () => { }); it('renders correct step heading', () => { - expect( - mountWithRouter().find( - 'EuiText' - ) - ).toMatchInlineSnapshot(` - -
- - - 4. STEP_NAME - - -
-
- `); + const { getByText } = render(); + + expect(getByText(`${step?.synthetics?.step?.index}. ${step?.synthetics?.step?.name}`)); }); it('renders a link to the step detail view', () => { diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/use_monitor_breadcrumbs.test.tsx b/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/use_monitor_breadcrumbs.test.tsx index 290f9f4bb0423..a8efd1f79c99c 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/use_monitor_breadcrumbs.test.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/use_monitor_breadcrumbs.test.tsx @@ -8,16 +8,37 @@ import { ChromeBreadcrumb } from 'kibana/public'; import React from 'react'; import { Route } from 'react-router-dom'; import { of } from 'rxjs'; -import { MountWithReduxProvider, mountWithRouter } from '../../../../lib'; -import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public'; +import { render } from '../../../../lib/helper/rtl_helpers'; import { useMonitorBreadcrumb } from './use_monitor_breadcrumb'; import { OVERVIEW_ROUTE } from '../../../../../common/constants'; import { Ping } from '../../../../../common/runtime_types/ping'; import { JourneyState } from '../../../../state/reducers/journey'; +import { chromeServiceMock, uiSettingsServiceMock } from 'src/core/public/mocks'; describe('useMonitorBreadcrumbs', () => { it('sets the given breadcrumbs', () => { - const [getBreadcrumbs, core] = mockCore(); + let breadcrumbObj: ChromeBreadcrumb[] = []; + const getBreadcrumbs = () => { + return breadcrumbObj; + }; + + const core = { + chrome: { + ...chromeServiceMock.createStartContract(), + setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => { + breadcrumbObj = newBreadcrumbs; + }, + }, + uiSettings: { + ...uiSettingsServiceMock.createSetupContract(), + get(key: string, defaultOverride?: any): any { + return `MMM D, YYYY @ HH:mm:ss.SSS` || defaultOverride; + }, + get$(key: string, defaultOverride?: any): any { + return of(`MMM D, YYYY @ HH:mm:ss.SSS`) || of(defaultOverride); + }, + }, + }; const Component = () => { useMonitorBreadcrumb({ @@ -27,14 +48,11 @@ describe('useMonitorBreadcrumbs', () => { return <>Step Water Fall; }; - mountWithRouter( - - - - - - - + render( + + + , + { core } ); expect(getBreadcrumbs()).toMatchInlineSnapshot(` @@ -56,27 +74,3 @@ describe('useMonitorBreadcrumbs', () => { `); }); }); - -const mockCore: () => [() => ChromeBreadcrumb[], any] = () => { - let breadcrumbObj: ChromeBreadcrumb[] = []; - const get = () => { - return breadcrumbObj; - }; - const core = { - application: { - getUrlForApp: () => '/app/uptime', - navigateToUrl: jest.fn(), - }, - chrome: { - setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => { - breadcrumbObj = newBreadcrumbs; - }, - }, - uiSettings: { - get: (key: string) => 'MMM D, YYYY @ HH:mm:ss.SSS', - get$: (key: string) => of('MMM D, YYYY @ HH:mm:ss.SSS'), - }, - }; - - return [get, core]; -}; diff --git a/x-pack/plugins/uptime/public/lib/__mocks__/uptime_store.mock.ts b/x-pack/plugins/uptime/public/lib/__mocks__/uptime_store.mock.ts index 0f600fcc20f6f..e6487503b4ded 100644 --- a/x-pack/plugins/uptime/public/lib/__mocks__/uptime_store.mock.ts +++ b/x-pack/plugins/uptime/public/lib/__mocks__/uptime_store.mock.ts @@ -5,12 +5,13 @@ */ import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../common/constants'; +import { AppState } from '../../state'; /** * NOTE: This variable name MUST start with 'mock*' in order for * Jest to accept its use within a jest.mock() */ -export const mockStore = { +export const mockState: AppState = { overviewFilters: { filters: { locations: [], @@ -111,8 +112,11 @@ export const mockStore = { alerts: { alertDeletion: { data: null, loading: false }, anomalyAlert: { data: null, loading: false }, + anomalyAlertDeletion: { data: null, loading: false }, alerts: { data: null, loading: false }, connectors: { data: null, loading: false }, newAlert: { data: null, loading: false }, }, + journeys: {}, + networkEvents: {}, }; diff --git a/x-pack/plugins/uptime/public/lib/helper/helper_with_router.tsx b/x-pack/plugins/uptime/public/lib/helper/enzyme_helpers.tsx similarity index 97% rename from x-pack/plugins/uptime/public/lib/helper/helper_with_router.tsx rename to x-pack/plugins/uptime/public/lib/helper/enzyme_helpers.tsx index 132552ef61a69..63792231017b3 100644 --- a/x-pack/plugins/uptime/public/lib/helper/helper_with_router.tsx +++ b/x-pack/plugins/uptime/public/lib/helper/enzyme_helpers.tsx @@ -5,13 +5,12 @@ */ import React, { ReactElement } from 'react'; - import { Router } from 'react-router-dom'; import { MemoryHistory } from 'history/createMemoryHistory'; import { createMemoryHistory } from 'history'; import { mountWithIntl, renderWithIntl, shallowWithIntl } from '@kbn/test/jest'; -import { AppState } from '../../state'; import { MountWithReduxProvider } from './helper_with_redux'; +import { AppState } from '../../state'; const helperWithRouter: ( helper: (node: ReactElement) => R, @@ -28,7 +27,7 @@ const helperWithRouter: ( if (wrapReduxStore) { return helper( - {routerWrapper} + {routerWrapper} ); } diff --git a/x-pack/plugins/uptime/public/lib/helper/helper_with_redux.tsx b/x-pack/plugins/uptime/public/lib/helper/helper_with_redux.tsx index 3c17d3510bfda..3b1cd143b33fb 100644 --- a/x-pack/plugins/uptime/public/lib/helper/helper_with_redux.tsx +++ b/x-pack/plugins/uptime/public/lib/helper/helper_with_redux.tsx @@ -8,11 +8,11 @@ import React from 'react'; import { Provider as ReduxProvider } from 'react-redux'; import { AppState } from '../../state'; -export const MountWithReduxProvider: React.FC<{ store?: AppState }> = ({ children, store }) => ( +export const MountWithReduxProvider: React.FC<{ state?: AppState }> = ({ children, state }) => ( { + core?: Partial & ExtraCore; + kibanaProps?: KibanaProps; +} + +interface MockKibanaProviderProps extends KibanaProviderOptions { + children: ReactElement; +} + +interface MockRouterProps extends MockKibanaProviderProps { + history?: History; +} + +interface RenderRouterOptions extends KibanaProviderOptions { + history?: History; + renderOptions?: Omit; + state?: Partial; +} + +/* default mock core */ +const defaultCore = coreMock.createStart(); +const mockCore: () => any = () => { + const core = { + ...defaultCore, + application: { + getUrlForApp: () => '/app/uptime', + navigateToUrl: jest.fn(), + }, + }; + + return core; +}; + +/* Mock Provider Components */ +export function MockKibanaProvider({ + children, + core, + kibanaProps, +}: MockKibanaProviderProps) { + const coreOptions = { + ...mockCore(), + ...core, + }; + return ( + + {children} + + ); +} + +export function MockRouter({ + children, + core, + history: customHistory, + kibanaProps, +}: MockRouterProps) { + const history = customHistory || createMemoryHistory(); + return ( + + + {children} + + + ); +} + +/* Custom react testing library render */ +export function render( + ui: ReactElement, + { history, core, kibanaProps, renderOptions, state }: RenderRouterOptions = {} +) { + const testState: AppState = { + ...mockState, + ...state, + }; + return reactTestLibRender( + + + {ui} + + , + renderOptions + ); +} diff --git a/x-pack/plugins/uptime/public/lib/index.ts b/x-pack/plugins/uptime/public/lib/index.ts index 7e800cc1eae95..85cce4fd549d5 100644 --- a/x-pack/plugins/uptime/public/lib/index.ts +++ b/x-pack/plugins/uptime/public/lib/index.ts @@ -5,4 +5,4 @@ */ export { MountWithReduxProvider } from './helper'; -export * from './helper/helper_with_router'; +export * from './helper/enzyme_helpers'; From e8285668a7b39d667f283252cd47b96898ad3386 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Tue, 12 Jan 2021 02:43:03 +0000 Subject: [PATCH 25/64] chore(NA): move missing apm plugin tests out of __tests__ folder (#87894) --- .../WaterfallWithSummmary/{__tests__ => }/ErrorCount.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/{__tests__ => }/ErrorCount.test.tsx (89%) diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/__tests__/ErrorCount.test.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/ErrorCount.test.tsx similarity index 89% rename from x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/__tests__/ErrorCount.test.tsx rename to x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/ErrorCount.test.tsx index 40b8a57f55051..2bfa820ee5e76 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/__tests__/ErrorCount.test.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/ErrorCount.test.tsx @@ -6,8 +6,8 @@ import { fireEvent, render } from '@testing-library/react'; import React from 'react'; -import { expectTextsInDocument } from '../../../../../utils/testHelpers'; -import { ErrorCount } from '../ErrorCount'; +import { expectTextsInDocument } from '../../../../utils/testHelpers'; +import { ErrorCount } from './ErrorCount'; describe('ErrorCount', () => { it('shows singular error message', () => { From 5dca937c0178427790ba56026ff07d51ffbe9bfa Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Tue, 12 Jan 2021 02:44:07 +0000 Subject: [PATCH 26/64] chore(NA): move reporting plugin test fixtures out of __tests__ folder (#87888) * chore(NA): move reporting plugin test fixtures out of __tests__ folder * fix(NA): fix a test import --- .../{__tests__ => }/__fixtures__/file.md | 0 .../{__tests__ => }/__fixtures__/file.md.zip | Bin .../{__tests__/extract.js => extract.test.js} | 15 ++++---- .../server/lib/create_worker.test.ts | 2 +- .../fixtures => __fixtures__}/job.js | 0 .../legacy_elasticsearch.js | 0 .../fixtures => __fixtures__}/queue.js | 0 .../fixtures => __fixtures__}/worker.js | 0 .../errors.js => helpers/errors.test.js} | 21 ++++++----- .../{__tests__/index.js => index.test.js} | 13 +++---- .../{__tests__/worker.js => worker.test.js} | 13 +++---- ...istry.js => export_types_registry.test.js} | 33 +++++++++--------- 12 files changed, 48 insertions(+), 49 deletions(-) rename x-pack/plugins/reporting/server/browsers/extract/{__tests__ => }/__fixtures__/file.md (100%) rename x-pack/plugins/reporting/server/browsers/extract/{__tests__ => }/__fixtures__/file.md.zip (100%) rename x-pack/plugins/reporting/server/browsers/extract/{__tests__/extract.js => extract.test.js} (88%) rename x-pack/plugins/reporting/server/lib/esqueue/{__tests__/fixtures => __fixtures__}/job.js (100%) rename x-pack/plugins/reporting/server/lib/esqueue/{__tests__/fixtures => __fixtures__}/legacy_elasticsearch.js (100%) rename x-pack/plugins/reporting/server/lib/esqueue/{__tests__/fixtures => __fixtures__}/queue.js (100%) rename x-pack/plugins/reporting/server/lib/esqueue/{__tests__/fixtures => __fixtures__}/worker.js (100%) rename x-pack/plugins/reporting/server/lib/esqueue/{__tests__/helpers/errors.js => helpers/errors.test.js} (67%) rename x-pack/plugins/reporting/server/lib/esqueue/{__tests__/index.js => index.test.js} (92%) rename x-pack/plugins/reporting/server/lib/esqueue/{__tests__/worker.js => worker.test.js} (99%) rename x-pack/plugins/reporting/server/lib/{__tests__/export_types_registry.js => export_types_registry.test.js} (86%) diff --git a/x-pack/plugins/reporting/server/browsers/extract/__tests__/__fixtures__/file.md b/x-pack/plugins/reporting/server/browsers/extract/__fixtures__/file.md similarity index 100% rename from x-pack/plugins/reporting/server/browsers/extract/__tests__/__fixtures__/file.md rename to x-pack/plugins/reporting/server/browsers/extract/__fixtures__/file.md diff --git a/x-pack/plugins/reporting/server/browsers/extract/__tests__/__fixtures__/file.md.zip b/x-pack/plugins/reporting/server/browsers/extract/__fixtures__/file.md.zip similarity index 100% rename from x-pack/plugins/reporting/server/browsers/extract/__tests__/__fixtures__/file.md.zip rename to x-pack/plugins/reporting/server/browsers/extract/__fixtures__/file.md.zip diff --git a/x-pack/plugins/reporting/server/browsers/extract/__tests__/extract.js b/x-pack/plugins/reporting/server/browsers/extract/extract.test.js similarity index 88% rename from x-pack/plugins/reporting/server/browsers/extract/__tests__/extract.js rename to x-pack/plugins/reporting/server/browsers/extract/extract.test.js index ab13703a90ed5..243a53e645bc9 100644 --- a/x-pack/plugins/reporting/server/browsers/extract/__tests__/extract.js +++ b/x-pack/plugins/reporting/server/browsers/extract/extract.test.js @@ -6,11 +6,10 @@ import fs from 'fs'; import crypto from 'crypto'; -import expect from '@kbn/expect'; import { resolve } from 'path'; -import { extract } from '../extract'; -import { ExtractError } from '../extract_error'; +import { extract } from './extract'; +import { ExtractError } from './extract_error'; import { promisify } from 'util'; const FIXTURES_FOLDER = resolve(__dirname, '__fixtures__'); @@ -71,18 +70,18 @@ describe('extract', () => { thrownException = e; } - expect(thrownException).to.be.an(ExtractError); + expect(thrownException).toBeInstanceOf(ExtractError); }); it('successfully extracts a valid zip file to the given target', async () => { await extract(SRC_FILE_COMPRESSED_ZIP, EXTRACT_TARGET_FOLDER); const stats = fs.statSync(EXTRACT_TARGET_FILE); - expect(stats).to.be.an(Object); + expect(stats).toBeInstanceOf(fs.Stats); const srcFileHash = await fileHash(SRC_FILE_UNCOMPRESSED); const targetFileHash = await fileHash(EXTRACT_TARGET_FILE); - expect(targetFileHash).to.eql(srcFileHash); + expect(targetFileHash).toEqual(srcFileHash); }); if (isWindows) { @@ -100,8 +99,8 @@ describe('extract', () => { thrownException = e; } - expect(thrownException).to.be.an(ExtractError); - expect(thrownException.cause.code).to.eql('EACCES'); + expect(thrownException).toBeInstanceOf(ExtractError); + expect(thrownException.cause.code).toEqual('EACCES'); }); } }); diff --git a/x-pack/plugins/reporting/server/lib/create_worker.test.ts b/x-pack/plugins/reporting/server/lib/create_worker.test.ts index 1fcd750849331..3ba5816beaf42 100644 --- a/x-pack/plugins/reporting/server/lib/create_worker.test.ts +++ b/x-pack/plugins/reporting/server/lib/create_worker.test.ts @@ -16,7 +16,7 @@ import { createWorkerFactory } from './create_worker'; // @ts-ignore import { Esqueue } from './esqueue'; // @ts-ignore -import { ClientMock } from './esqueue/__tests__/fixtures/legacy_elasticsearch'; +import { ClientMock } from './esqueue/__fixtures__/legacy_elasticsearch'; import { ExportTypesRegistry } from './export_types_registry'; const logger = createMockLevelLogger(); diff --git a/x-pack/plugins/reporting/server/lib/esqueue/__tests__/fixtures/job.js b/x-pack/plugins/reporting/server/lib/esqueue/__fixtures__/job.js similarity index 100% rename from x-pack/plugins/reporting/server/lib/esqueue/__tests__/fixtures/job.js rename to x-pack/plugins/reporting/server/lib/esqueue/__fixtures__/job.js diff --git a/x-pack/plugins/reporting/server/lib/esqueue/__tests__/fixtures/legacy_elasticsearch.js b/x-pack/plugins/reporting/server/lib/esqueue/__fixtures__/legacy_elasticsearch.js similarity index 100% rename from x-pack/plugins/reporting/server/lib/esqueue/__tests__/fixtures/legacy_elasticsearch.js rename to x-pack/plugins/reporting/server/lib/esqueue/__fixtures__/legacy_elasticsearch.js diff --git a/x-pack/plugins/reporting/server/lib/esqueue/__tests__/fixtures/queue.js b/x-pack/plugins/reporting/server/lib/esqueue/__fixtures__/queue.js similarity index 100% rename from x-pack/plugins/reporting/server/lib/esqueue/__tests__/fixtures/queue.js rename to x-pack/plugins/reporting/server/lib/esqueue/__fixtures__/queue.js diff --git a/x-pack/plugins/reporting/server/lib/esqueue/__tests__/fixtures/worker.js b/x-pack/plugins/reporting/server/lib/esqueue/__fixtures__/worker.js similarity index 100% rename from x-pack/plugins/reporting/server/lib/esqueue/__tests__/fixtures/worker.js rename to x-pack/plugins/reporting/server/lib/esqueue/__fixtures__/worker.js diff --git a/x-pack/plugins/reporting/server/lib/esqueue/__tests__/helpers/errors.js b/x-pack/plugins/reporting/server/lib/esqueue/helpers/errors.test.js similarity index 67% rename from x-pack/plugins/reporting/server/lib/esqueue/__tests__/helpers/errors.js rename to x-pack/plugins/reporting/server/lib/esqueue/helpers/errors.test.js index d41b29106bb9d..a188add2d1ddc 100644 --- a/x-pack/plugins/reporting/server/lib/esqueue/__tests__/helpers/errors.js +++ b/x-pack/plugins/reporting/server/lib/esqueue/helpers/errors.test.js @@ -4,54 +4,53 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from '@kbn/expect'; -import { WorkerTimeoutError, UnspecifiedWorkerError } from '../../helpers/errors'; +import { WorkerTimeoutError, UnspecifiedWorkerError } from './errors'; describe('custom errors', function () { describe('WorkerTimeoutError', function () { it('should be function', () => { - expect(WorkerTimeoutError).to.be.a('function'); + expect(typeof WorkerTimeoutError).toBe('function'); }); it('should have a name', function () { const err = new WorkerTimeoutError('timeout error'); - expect(err).to.have.property('name', 'WorkerTimeoutError'); + expect(err).toHaveProperty('name', 'WorkerTimeoutError'); }); it('should take a jobId property', function () { const err = new WorkerTimeoutError('timeout error', { jobId: 'il7hl34rqlo8ro' }); - expect(err).to.have.property('jobId', 'il7hl34rqlo8ro'); + expect(err).toHaveProperty('jobId', 'il7hl34rqlo8ro'); }); it('should take a timeout property', function () { const err = new WorkerTimeoutError('timeout error', { timeout: 15000 }); - expect(err).to.have.property('timeout', 15000); + expect(err).toHaveProperty('timeout', 15000); }); it('should be stringifyable', function () { const err = new WorkerTimeoutError('timeout error'); - expect(`${err}`).to.equal('WorkerTimeoutError: timeout error'); + expect(`${err}`).toEqual('WorkerTimeoutError: timeout error'); }); }); describe('UnspecifiedWorkerError', function () { it('should be function', () => { - expect(UnspecifiedWorkerError).to.be.a('function'); + expect(typeof UnspecifiedWorkerError).toBe('function'); }); it('should have a name', function () { const err = new UnspecifiedWorkerError('unspecified error'); - expect(err).to.have.property('name', 'UnspecifiedWorkerError'); + expect(err).toHaveProperty('name', 'UnspecifiedWorkerError'); }); it('should take a jobId property', function () { const err = new UnspecifiedWorkerError('unspecified error', { jobId: 'il7hl34rqlo8ro' }); - expect(err).to.have.property('jobId', 'il7hl34rqlo8ro'); + expect(err).toHaveProperty('jobId', 'il7hl34rqlo8ro'); }); it('should be stringifyable', function () { const err = new UnspecifiedWorkerError('unspecified error'); - expect(`${err}`).to.equal('UnspecifiedWorkerError: unspecified error'); + expect(`${err}`).toEqual('UnspecifiedWorkerError: unspecified error'); }); }); }); diff --git a/x-pack/plugins/reporting/server/lib/esqueue/__tests__/index.js b/x-pack/plugins/reporting/server/lib/esqueue/index.test.js similarity index 92% rename from x-pack/plugins/reporting/server/lib/esqueue/__tests__/index.js rename to x-pack/plugins/reporting/server/lib/esqueue/index.test.js index 7cdae152ad0d7..072614e69d5a5 100644 --- a/x-pack/plugins/reporting/server/lib/esqueue/__tests__/index.js +++ b/x-pack/plugins/reporting/server/lib/esqueue/index.test.js @@ -9,17 +9,18 @@ import expect from '@kbn/expect'; import sinon from 'sinon'; import proxyquire from 'proxyquire'; import { noop, times } from 'lodash'; -import { constants } from '../constants'; -import { ClientMock } from './fixtures/legacy_elasticsearch'; -import { JobMock } from './fixtures/job'; -import { WorkerMock } from './fixtures/worker'; +import { constants } from './constants'; +import { ClientMock } from './__fixtures__/legacy_elasticsearch'; +import { JobMock } from './__fixtures__/job'; +import { WorkerMock } from './__fixtures__/worker'; -const { Esqueue } = proxyquire.noPreserveCache()('../index', { +const { Esqueue } = proxyquire.noPreserveCache()('./index', { './job': { Job: JobMock }, './worker': { Worker: WorkerMock }, }); -describe('Esqueue class', function () { +// TODO: tests were not running and are not up to date +describe.skip('Esqueue class', function () { let client; beforeEach(function () { diff --git a/x-pack/plugins/reporting/server/lib/esqueue/__tests__/worker.js b/x-pack/plugins/reporting/server/lib/esqueue/worker.test.js similarity index 99% rename from x-pack/plugins/reporting/server/lib/esqueue/__tests__/worker.js rename to x-pack/plugins/reporting/server/lib/esqueue/worker.test.js index b31a39a6f90cc..59a12c86cba9f 100644 --- a/x-pack/plugins/reporting/server/lib/esqueue/__tests__/worker.js +++ b/x-pack/plugins/reporting/server/lib/esqueue/worker.test.js @@ -8,10 +8,10 @@ import expect from '@kbn/expect'; import sinon from 'sinon'; import moment from 'moment'; import { noop, random, get, find, identity } from 'lodash'; -import { ClientMock } from './fixtures/legacy_elasticsearch'; -import { QueueMock } from './fixtures/queue'; -import { formatJobObject, getUpdatedDocPath, Worker } from '../worker'; -import { constants } from '../constants'; +import { ClientMock } from './__fixtures__/legacy_elasticsearch'; +import { QueueMock } from './__fixtures__/queue'; +import { formatJobObject, getUpdatedDocPath, Worker } from './worker'; +import { constants } from './constants'; const anchor = '2016-04-02T01:02:03.456'; // saturday const defaults = { @@ -26,9 +26,10 @@ const defaultWorkerOptions = { intervalErrorMultiplier: 10, }; -describe('Worker class', function () { +// TODO: tests were not running and are not up to date +describe.skip('Worker class', function () { // some of these tests might be a little slow, give them a little extra time - this.timeout(10000); + jest.setTimeout(10000); let anchorMoment; let clock; diff --git a/x-pack/plugins/reporting/server/lib/__tests__/export_types_registry.js b/x-pack/plugins/reporting/server/lib/export_types_registry.test.js similarity index 86% rename from x-pack/plugins/reporting/server/lib/__tests__/export_types_registry.js rename to x-pack/plugins/reporting/server/lib/export_types_registry.test.js index 3f8b7e7e75af1..1afeaa4bba950 100644 --- a/x-pack/plugins/reporting/server/lib/__tests__/export_types_registry.js +++ b/x-pack/plugins/reporting/server/lib/export_types_registry.test.js @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from '@kbn/expect'; -import { ExportTypesRegistry } from '../export_types_registry'; +import { ExportTypesRegistry } from './export_types_registry'; describe('ExportTypesRegistry', function () { let exportTypesRegistry; @@ -17,30 +16,30 @@ describe('ExportTypesRegistry', function () { it(`doesn't throw an Error when using a new type with a string id`, function () { expect(() => { exportTypesRegistry.register({ id: 'foo' }); - }).to.not.throwError(); + }).not.toThrow(); }); it('throws an Error when registering a type without an id', function () { expect(() => { exportTypesRegistry.register({}); - }).to.throwError(); + }).toThrow(); }); it('throws an Error when registering a type with an integer id', function () { expect(() => { exportTypesRegistry.register({ id: 1 }); - }).to.throwError(); + }).toThrow(); }); it('throws an Error when registering the same id twice', function () { const id = 'foo'; expect(() => { exportTypesRegistry.register({ id }); - }).to.not.throwError(); + }).not.toThrow(); expect(() => { exportTypesRegistry.register({ id }); - }).to.throwError(); + }).toThrow(); }); }); @@ -50,20 +49,20 @@ describe('ExportTypesRegistry', function () { const obj = { id }; exportTypesRegistry.register(obj); exportTypesRegistry.register({ id: 'bar' }); - expect(exportTypesRegistry.getById(id)).to.be(obj); + expect(exportTypesRegistry.getById(id)).toBe(obj); }); it(`throws an Error if the id isn't found`, function () { expect(() => { exportTypesRegistry.getById('foo'); - }).to.throwError(); + }).toThrow(); }); }); describe('getAll', function () { it('returns an empty Iterator if no objects have been registered', function () { const array = Array.from(exportTypesRegistry.getAll()); - expect(array.length).to.be(0); + expect(array.length).toBe(0); }); it('returns all objects that have been registered', function () { @@ -72,15 +71,15 @@ describe('ExportTypesRegistry', function () { const objs = [obj1, obj2]; objs.forEach((obj) => exportTypesRegistry.register(obj)); const all = Array.from(exportTypesRegistry.getAll()); - expect(all).to.contain(obj1); - expect(all).to.contain(obj2); + expect(all).toContain(obj1); + expect(all).toContain(obj2); }); }); describe('getSize', function () { it('returns 0 initially', function () { const size = exportTypesRegistry.getSize(); - expect(size).to.be(0); + expect(size).toBe(0); }); it('returns the number of objects that have been added', function () { @@ -88,7 +87,7 @@ describe('ExportTypesRegistry', function () { exportTypesRegistry.register({ id: 'bar' }); exportTypesRegistry.register({ id: 'baz' }); const size = exportTypesRegistry.getSize(); - expect(size).to.be(3); + expect(size).toBe(3); }); }); @@ -97,7 +96,7 @@ describe('ExportTypesRegistry', function () { const prop = 'fooProp'; const match = { id: 'foo', prop }; [match, { id: 'bar' }, { id: 'baz' }].forEach((obj) => exportTypesRegistry.register(obj)); - expect(exportTypesRegistry.get((item) => item.prop === prop)).to.be(match); + expect(exportTypesRegistry.get((item) => item.prop === prop)).toBe(match); }); it('throws Error if multiple items match predicate', function () { @@ -108,7 +107,7 @@ describe('ExportTypesRegistry', function () { ].forEach((obj) => exportTypesRegistry.register(obj)); expect(() => { exportTypesRegistry.get((item) => item.prop === prop); - }).to.throwError(); + }).toThrow(); }); it('throws Error if no items match predicate', function () { @@ -119,7 +118,7 @@ describe('ExportTypesRegistry', function () { ].forEach((obj) => exportTypesRegistry.register(obj)); expect(() => { exportTypesRegistry.get((item) => item.prop !== prop); - }).to.throwError(); + }).toThrow(); }); }); }); From 46083c0973211ec6bd60ab873a4501cc558d6a78 Mon Sep 17 00:00:00 2001 From: Andrew Goldstein Date: Tue, 12 Jan 2021 01:02:53 -0700 Subject: [PATCH 27/64] [Security Solution] Accessibility (a11y) fixes (#87783) ## [Security Solution] Accessibility (a11y) fixes This PR fixes the following accessibility (a11y) issues: - Fixes an issue that prevented tabbing through all elements on pages with embedded Timelines - Fixes an issue where the Timeline data providers popover menu was not displayed when Enter is pressed - Fixes an issue where duplicate draggable IDs caused errors when re-arranging Timeline columns - Fixes an issue where Timeline columns could not be removed or sorted via keyboard - Fixes an issue where focus is not restored to the `Customize Columns` button when the `Reset` button is pressed - Fixes an issue where filtering the `Customize Event Renderers` view via the input cleared selected entries - Fixes an issue where the active timeline button wasn't focused when Timeline is closed - Fixes an issue where the `(+)` Create / Open Timeline button's hover panel didn't own focus --- .../integration/fields_browser.spec.ts | 15 ++ .../timeline_data_providers.spec.ts | 12 ++ .../timeline_flyout_button.spec.ts | 42 ++++- .../cypress/screens/security_main.ts | 2 + .../cypress/screens/timeline.ts | 2 + .../cypress/tasks/security_main.ts | 5 + .../alerts_table/alerts_utility_bar/index.tsx | 2 +- .../detection_engine/detection_engine.tsx | 37 +++- .../detection_engine/rules/details/index.tsx | 37 +++- .../public/hosts/pages/hosts.tsx | 38 +++- .../public/network/pages/network.tsx | 39 +++- .../fields_browser/field_browser.tsx | 2 +- .../flyout/add_timeline_button/index.tsx | 1 + .../components/flyout/bottom_bar/index.tsx | 9 +- .../flyout/header/active_timelines.tsx | 14 +- .../components/flyout/header/index.tsx | 9 +- .../components/flyout/pane/index.tsx | 9 +- .../row_renderers_browser/index.tsx | 15 +- .../row_renderers_browser.tsx | 174 ++++++++---------- .../__snapshots__/index.test.tsx.snap | 1 + .../body/column_headers/column_header.tsx | 152 +++++++++++++-- .../body/column_headers/index.test.tsx | 7 + .../timeline/body/column_headers/index.tsx | 9 +- .../body/column_headers/translations.ts | 12 ++ .../components/timeline/body/index.tsx | 1 + .../__snapshots__/provider.test.tsx.snap | 2 + .../timeline/data_providers/provider.tsx | 40 ++-- .../data_providers/provider_item_actions.tsx | 1 + .../data_providers/provider_item_badge.tsx | 9 +- .../timeline/data_providers/providers.tsx | 19 +- .../timelines/components/timeline/helpers.tsx | 37 ++++ .../timelines/components/timeline/styles.tsx | 1 + 32 files changed, 575 insertions(+), 180 deletions(-) diff --git a/x-pack/plugins/security_solution/cypress/integration/fields_browser.spec.ts b/x-pack/plugins/security_solution/cypress/integration/fields_browser.spec.ts index 55ded8014db3c..e65cbf85e6e73 100644 --- a/x-pack/plugins/security_solution/cypress/integration/fields_browser.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/fields_browser.spec.ts @@ -16,6 +16,7 @@ import { FIELDS_BROWSER_SELECTED_CATEGORY_COUNT, FIELDS_BROWSER_SYSTEM_CATEGORIES_COUNT, } from '../screens/fields_browser'; +import { TIMELINE_FIELDS_BUTTON } from '../screens/timeline'; import { cleanKibana } from '../tasks/common'; import { @@ -182,5 +183,19 @@ describe('Fields Browser', () => { cy.get(FIELDS_BROWSER_HEADER_HOST_GEO_CONTINENT_NAME_HEADER).should('not.exist'); }); + + it('restores focus to the Customize Columns button when `Reset Fields` is clicked', () => { + openTimelineFieldsBrowser(); + resetFields(); + + cy.get(TIMELINE_FIELDS_BUTTON).should('have.focus'); + }); + + it('restores focus to the Customize Columns button when Esc is pressed', () => { + openTimelineFieldsBrowser(); + cy.get('body').type('{esc}'); + + cy.get(TIMELINE_FIELDS_BUTTON).should('have.focus'); + }); }); }); diff --git a/x-pack/plugins/security_solution/cypress/integration/timeline_data_providers.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timeline_data_providers.spec.ts index 32ffb01b8ff55..5c8fea7319fc3 100644 --- a/x-pack/plugins/security_solution/cypress/integration/timeline_data_providers.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/timeline_data_providers.spec.ts @@ -8,6 +8,7 @@ import { TIMELINE_DATA_PROVIDERS, TIMELINE_DATA_PROVIDERS_EMPTY, TIMELINE_DROPPED_DATA_PROVIDERS, + TIMELINE_DATA_PROVIDERS_ACTION_MENU, } from '../screens/timeline'; import { HOSTS_NAMES_DRAGGABLE } from '../screens/hosts/all_hosts'; @@ -53,6 +54,17 @@ describe('timeline data providers', () => { }); }); + it('displays the data provider action menu when Enter is pressed', () => { + dragAndDropFirstHostToTimeline(); + openTimelineUsingToggle(); + cy.get(TIMELINE_DATA_PROVIDERS_ACTION_MENU).should('not.exist'); + + cy.get(TIMELINE_DROPPED_DATA_PROVIDERS).first().focus(); + cy.get(TIMELINE_DROPPED_DATA_PROVIDERS).first().parent().type('{enter}'); + + cy.get(TIMELINE_DATA_PROVIDERS_ACTION_MENU).should('exist'); + }); + it('sets the background to euiColorSuccess with a 10% alpha channel when the user starts dragging a host, but is not hovering over the data providers', () => { dragFirstHostToTimeline(); diff --git a/x-pack/plugins/security_solution/cypress/integration/timeline_flyout_button.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timeline_flyout_button.spec.ts index acf245251d7e1..a09f1c1875064 100644 --- a/x-pack/plugins/security_solution/cypress/integration/timeline_flyout_button.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/timeline_flyout_button.spec.ts @@ -4,12 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ -import { TIMELINE_FLYOUT_HEADER, TIMELINE_DATA_PROVIDERS } from '../screens/timeline'; +import { TIMELINE_BOTTOM_BAR_TOGGLE_BUTTON } from '../screens/security_main'; +import { + CREATE_NEW_TIMELINE, + TIMELINE_DATA_PROVIDERS, + TIMELINE_FLYOUT_HEADER, + TIMELINE_SETTINGS_ICON, +} from '../screens/timeline'; import { cleanKibana } from '../tasks/common'; import { dragFirstHostToTimeline, waitForAllHostsToBeLoaded } from '../tasks/hosts/all_hosts'; import { loginAndWaitForPage } from '../tasks/login'; -import { openTimelineUsingToggle, closeTimelineUsingToggle } from '../tasks/security_main'; +import { + closeTimelineUsingCloseButton, + closeTimelineUsingToggle, + openTimelineUsingToggle, +} from '../tasks/security_main'; import { HOSTS_URL } from '../urls/navigation'; @@ -26,6 +36,34 @@ describe('timeline flyout button', () => { closeTimelineUsingToggle(); }); + it('re-focuses the toggle button when timeline is closed by clicking the active timeline toggle button', () => { + openTimelineUsingToggle(); + closeTimelineUsingToggle(); + + cy.get(TIMELINE_BOTTOM_BAR_TOGGLE_BUTTON).should('have.focus'); + }); + + it('re-focuses the toggle button when timeline is closed by clicking the [X] close button', () => { + openTimelineUsingToggle(); + closeTimelineUsingCloseButton(); + + cy.get(TIMELINE_BOTTOM_BAR_TOGGLE_BUTTON).should('have.focus'); + }); + + it('re-focuses the toggle button when timeline is closed by pressing the Esc key', () => { + openTimelineUsingToggle(); + cy.get('body').type('{esc}'); + + cy.get(TIMELINE_BOTTOM_BAR_TOGGLE_BUTTON).should('have.focus'); + }); + + it('the `(+)` button popover menu owns focus', () => { + cy.get(TIMELINE_SETTINGS_ICON).filter(':visible').click({ force: true }); + cy.get(CREATE_NEW_TIMELINE).should('have.focus'); + cy.get('body').type('{esc}'); + cy.get(CREATE_NEW_TIMELINE).should('not.be.visible'); + }); + it('sets the data providers background to euiColorSuccess with a 10% alpha channel when the user starts dragging a host, but is not hovering over the data providers area', () => { dragFirstHostToTimeline(); diff --git a/x-pack/plugins/security_solution/cypress/screens/security_main.ts b/x-pack/plugins/security_solution/cypress/screens/security_main.ts index c6c1067825f16..22f7cd68659bd 100644 --- a/x-pack/plugins/security_solution/cypress/screens/security_main.ts +++ b/x-pack/plugins/security_solution/cypress/screens/security_main.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +export const CLOSE_TIMELINE_BUTTON = '[data-test-subj="close-timeline"]'; + export const MAIN_PAGE = '[data-test-subj="kibanaChrome"]'; export const TIMELINE_TOGGLE_BUTTON = '[data-test-subj="flyoutOverlay"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/timeline.ts b/x-pack/plugins/security_solution/cypress/screens/timeline.ts index fef94da062e01..42d2b699fc8d5 100644 --- a/x-pack/plugins/security_solution/cypress/screens/timeline.ts +++ b/x-pack/plugins/security_solution/cypress/screens/timeline.ts @@ -111,6 +111,8 @@ export const TIMELINE_COLUMN_SPINNER = '[data-test-subj="timeline-loading-spinne export const TIMELINE_DATA_PROVIDERS = '[data-test-subj="dataProviders"]'; +export const TIMELINE_DATA_PROVIDERS_ACTION_MENU = '[data-test-subj="providerActions"]'; + export const TIMELINE_DATA_PROVIDERS_EMPTY = '[data-test-subj="dataProviders"] [data-test-subj="empty"]'; diff --git a/x-pack/plugins/security_solution/cypress/tasks/security_main.ts b/x-pack/plugins/security_solution/cypress/tasks/security_main.ts index eb03c56ef04e8..05ba6e3223c9e 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/security_main.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/security_main.ts @@ -5,6 +5,7 @@ */ import { + CLOSE_TIMELINE_BUTTON, MAIN_PAGE, TIMELINE_TOGGLE_BUTTON, TIMELINE_BOTTOM_BAR_TOGGLE_BUTTON, @@ -18,6 +19,10 @@ export const closeTimelineUsingToggle = () => { cy.get(TIMELINE_TOGGLE_BUTTON).filter(':visible').click(); }; +export const closeTimelineUsingCloseButton = () => { + cy.get(CLOSE_TIMELINE_BUTTON).filter(':visible').click(); +}; + export const openTimelineIfClosed = () => cy.get(MAIN_PAGE).then(($page) => { if ($page.find(TIMELINE_BOTTOM_BAR_TOGGLE_BUTTON).length === 1) { diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx index fc7385f807cbe..3b3cbcbd72fd2 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx @@ -220,7 +220,7 @@ const AlertsUtilityBarComponent: React.FC = ({ disabled={areEventsLoading} iconType="arrowDown" iconSide="right" - ownFocus={false} + ownFocus={true} popoverContent={UtilityBarAdditionalFiltersContent} > {i18n.ADDITIONAL_FILTERS_ACTIONS} diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx index fe1b6933763f4..4a8f8a586e08b 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx @@ -6,7 +6,7 @@ import { EuiSpacer, EuiWindowEvent } from '@elastic/eui'; import { noop } from 'lodash/fp'; -import React, { useCallback, useMemo, useState } from 'react'; +import React, { useCallback, useMemo, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; import { useHistory } from 'react-router-dom'; @@ -14,6 +14,7 @@ import { useDeepEqualSelector, useShallowEqualSelector } from '../../../common/h import { SecurityPageName } from '../../../app/types'; import { TimelineId } from '../../../../common/types/timeline'; import { useGlobalTime } from '../../../common/containers/use_global_time'; +import { isTab } from '../../../common/components/accessibility/helpers'; import { UpdateDateRange } from '../../../common/components/charts/common'; import { FiltersGlobal } from '../../../common/components/filters_global'; import { getRulesUrl } from '../../../common/components/link_to/redirect_to_detection_engine'; @@ -39,7 +40,12 @@ import { LinkButton } from '../../../common/components/links'; import { useFormatUrl } from '../../../common/components/link_to'; import { useGlobalFullScreen } from '../../../common/containers/use_full_screen'; import { Display } from '../../../hosts/pages/display'; -import { showGlobalFilters } from '../../../timelines/components/timeline/helpers'; +import { + focusUtilityBarAction, + onTimelineTabKeyPressed, + resetKeyboardFocus, + showGlobalFilters, +} from '../../../timelines/components/timeline/helpers'; import { timelineSelectors } from '../../../timelines/store/timeline'; import { timelineDefaults } from '../../../timelines/store/timeline/defaults'; import { buildShowBuildingBlockFilter } from '../../components/alerts_table/default_config'; @@ -48,6 +54,7 @@ import { SourcererScopeName } from '../../../common/store/sourcerer/model'; const DetectionEnginePageComponent = () => { const dispatch = useDispatch(); + const containerElement = useRef(null); const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []); const graphEventId = useShallowEqualSelector( (state) => (getTimeline(state, TimelineId.detectionsPage) ?? timelineDefaults).graphEventId @@ -128,6 +135,28 @@ const DetectionEnginePageComponent = () => { const { indicesExist, indexPattern } = useSourcererScope(SourcererScopeName.detections); + const onSkipFocusBeforeEventsTable = useCallback(() => { + focusUtilityBarAction(containerElement.current); + }, [containerElement]); + + const onSkipFocusAfterEventsTable = useCallback(() => { + resetKeyboardFocus(); + }, []); + + const onKeyDown = useCallback( + (keyboardEvent: React.KeyboardEvent) => { + if (isTab(keyboardEvent)) { + onTimelineTabKeyPressed({ + containerElement: containerElement.current, + keyboardEvent, + onSkipFocusBeforeEventsTable, + onSkipFocusAfterEventsTable, + }); + } + }, + [containerElement, onSkipFocusBeforeEventsTable, onSkipFocusAfterEventsTable] + ); + if (isUserAuthenticated != null && !isUserAuthenticated && !loading) { return ( @@ -154,7 +183,7 @@ const DetectionEnginePageComponent = () => { {hasEncryptionKey != null && !hasEncryptionKey && } {indicesExist ? ( - <> +
@@ -211,7 +240,7 @@ const DetectionEnginePageComponent = () => { to={to} /> - +
) : ( diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx index 243413a7b6ac9..bcf28d2889a97 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx @@ -19,7 +19,7 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { noop } from 'lodash/fp'; -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useParams, useHistory } from 'react-router-dom'; import { useDispatch } from 'react-redux'; @@ -81,7 +81,12 @@ import { useGlobalFullScreen } from '../../../../../common/containers/use_full_s import { Display } from '../../../../../hosts/pages/display'; import { ExceptionListTypeEnum, ExceptionListIdentifiers } from '../../../../../shared_imports'; import { useRuleAsync } from '../../../../containers/detection_engine/rules/use_rule_async'; -import { showGlobalFilters } from '../../../../../timelines/components/timeline/helpers'; +import { + focusUtilityBarAction, + onTimelineTabKeyPressed, + resetKeyboardFocus, + showGlobalFilters, +} from '../../../../../timelines/components/timeline/helpers'; import { timelineSelectors } from '../../../../../timelines/store/timeline'; import { timelineDefaults } from '../../../../../timelines/store/timeline/defaults'; import { useSourcererScope } from '../../../../../common/containers/sourcerer'; @@ -95,6 +100,7 @@ import { import * as detectionI18n from '../../translations'; import * as ruleI18n from '../translations'; import * as i18n from './translations'; +import { isTab } from '../../../../../common/components/accessibility/helpers'; enum RuleDetailTabs { alerts = 'alerts', @@ -127,6 +133,7 @@ const getRuleDetailsTabs = (rule: Rule | null) => { const RuleDetailsPageComponent = () => { const dispatch = useDispatch(); + const containerElement = useRef(null); const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []); const graphEventId = useShallowEqualSelector( (state) => @@ -408,6 +415,28 @@ const RuleDetailsPageComponent = () => { } }, [rule]); + const onSkipFocusBeforeEventsTable = useCallback(() => { + focusUtilityBarAction(containerElement.current); + }, [containerElement]); + + const onSkipFocusAfterEventsTable = useCallback(() => { + resetKeyboardFocus(); + }, []); + + const onKeyDown = useCallback( + (keyboardEvent: React.KeyboardEvent) => { + if (isTab(keyboardEvent)) { + onTimelineTabKeyPressed({ + containerElement: containerElement.current, + keyboardEvent, + onSkipFocusBeforeEventsTable, + onSkipFocusAfterEventsTable, + }); + } + }, + [containerElement, onSkipFocusBeforeEventsTable, onSkipFocusAfterEventsTable] + ); + if ( redirectToDetections( isSignalIndexExists, @@ -430,7 +459,7 @@ const RuleDetailsPageComponent = () => { {indicesExist ? ( - <> +
@@ -588,7 +617,7 @@ const RuleDetailsPageComponent = () => { )} {ruleDetailTab === RuleDetailTabs.failures && } - +
) : ( diff --git a/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx b/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx index 52ec837a09eb6..0af60c268012c 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx @@ -6,7 +6,7 @@ import { EuiSpacer, EuiWindowEvent } from '@elastic/eui'; import { noop } from 'lodash/fp'; -import React, { useCallback, useMemo } from 'react'; +import React, { useCallback, useMemo, useRef } from 'react'; import { useDispatch } from 'react-redux'; import { useParams } from 'react-router-dom'; @@ -40,7 +40,12 @@ import * as i18n from './translations'; import { filterHostData } from './navigation'; import { hostsModel } from '../store'; import { HostsTableType } from '../store/model'; -import { showGlobalFilters } from '../../timelines/components/timeline/helpers'; +import { isTab } from '../../common/components/accessibility/helpers'; +import { + onTimelineTabKeyPressed, + resetKeyboardFocus, + showGlobalFilters, +} from '../../timelines/components/timeline/helpers'; import { timelineSelectors } from '../../timelines/store/timeline'; import { timelineDefaults } from '../../timelines/store/timeline/defaults'; import { useSourcererScope } from '../../common/containers/sourcerer'; @@ -48,6 +53,7 @@ import { useDeepEqualSelector, useShallowEqualSelector } from '../../common/hook const HostsComponent = () => { const dispatch = useDispatch(); + const containerElement = useRef(null); const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []); const graphEventId = useShallowEqualSelector( (state) => @@ -114,10 +120,34 @@ const HostsComponent = () => { [indexPattern, query, tabsFilters, uiSettings] ); + const onSkipFocusBeforeEventsTable = useCallback(() => { + containerElement.current + ?.querySelector('.inspectButtonComponent:last-of-type') + ?.focus(); + }, [containerElement]); + + const onSkipFocusAfterEventsTable = useCallback(() => { + resetKeyboardFocus(); + }, []); + + const onKeyDown = useCallback( + (keyboardEvent: React.KeyboardEvent) => { + if (isTab(keyboardEvent)) { + onTimelineTabKeyPressed({ + containerElement: containerElement.current, + keyboardEvent, + onSkipFocusBeforeEventsTable, + onSkipFocusAfterEventsTable, + }); + } + }, + [containerElement, onSkipFocusBeforeEventsTable, onSkipFocusAfterEventsTable] + ); + return ( <> {indicesExist ? ( - <> +
@@ -167,7 +197,7 @@ const HostsComponent = () => { type={hostsModel.HostsType.page} /> - +
) : ( diff --git a/x-pack/plugins/security_solution/public/network/pages/network.tsx b/x-pack/plugins/security_solution/public/network/pages/network.tsx index 3a095cfb21f0e..a9959fb3a326c 100644 --- a/x-pack/plugins/security_solution/public/network/pages/network.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/network.tsx @@ -6,7 +6,7 @@ import { EuiSpacer, EuiWindowEvent } from '@elastic/eui'; import { noop } from 'lodash/fp'; -import React, { useCallback, useMemo } from 'react'; +import React, { useCallback, useMemo, useRef } from 'react'; import { useDispatch } from 'react-redux'; import { useParams } from 'react-router-dom'; @@ -38,8 +38,13 @@ import { OverviewEmpty } from '../../overview/components/overview_empty'; import * as i18n from './translations'; import { NetworkComponentProps } from './types'; import { NetworkRouteType } from './navigation/types'; -import { showGlobalFilters } from '../../timelines/components/timeline/helpers'; +import { + onTimelineTabKeyPressed, + resetKeyboardFocus, + showGlobalFilters, +} from '../../timelines/components/timeline/helpers'; import { timelineSelectors } from '../../timelines/store/timeline'; +import { isTab } from '../../common/components/accessibility/helpers'; import { TimelineId } from '../../../common/types/timeline'; import { timelineDefaults } from '../../timelines/store/timeline/defaults'; import { useSourcererScope } from '../../common/containers/sourcerer'; @@ -48,6 +53,7 @@ import { useDeepEqualSelector, useShallowEqualSelector } from '../../common/hook const NetworkComponent = React.memo( ({ networkPagePath, hasMlUserPermissions, capabilitiesFetched }) => { const dispatch = useDispatch(); + const containerElement = useRef(null); const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []); const graphEventId = useShallowEqualSelector( (state) => @@ -91,6 +97,31 @@ const NetworkComponent = React.memo( ); const { docValueFields, indicesExist, indexPattern, selectedPatterns } = useSourcererScope(); + + const onSkipFocusBeforeEventsTable = useCallback(() => { + containerElement.current + ?.querySelector('.inspectButtonComponent:last-of-type') + ?.focus(); + }, [containerElement]); + + const onSkipFocusAfterEventsTable = useCallback(() => { + resetKeyboardFocus(); + }, []); + + const onKeyDown = useCallback( + (keyboardEvent: React.KeyboardEvent) => { + if (isTab(keyboardEvent)) { + onTimelineTabKeyPressed({ + containerElement: containerElement.current, + keyboardEvent, + onSkipFocusBeforeEventsTable, + onSkipFocusAfterEventsTable, + }); + } + }, + [containerElement, onSkipFocusBeforeEventsTable, onSkipFocusAfterEventsTable] + ); + const filterQuery = convertToBuildEsQuery({ config: esQuery.getEsQueryConfig(kibana.services.uiSettings), indexPattern, @@ -107,7 +138,7 @@ const NetworkComponent = React.memo( return ( <> {indicesExist ? ( - <> +
@@ -176,7 +207,7 @@ const NetworkComponent = React.memo( )} - +
) : ( diff --git a/x-pack/plugins/security_solution/public/timelines/components/fields_browser/field_browser.tsx b/x-pack/plugins/security_solution/public/timelines/components/fields_browser/field_browser.tsx index eabe94c088a54..525683cea186a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/fields_browser/field_browser.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/fields_browser/field_browser.tsx @@ -239,7 +239,7 @@ const FieldsBrowserComponent: React.FC = ({ data-test-subj="header" filteredBrowserFields={filteredBrowserFields} isSearching={isSearching} - onOutsideClick={onOutsideClick} + onOutsideClick={closeAndRestoreFocus} onSearchInputChange={onInputChange} onUpdateColumns={onUpdateColumns} searchInput={searchInput} diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/add_timeline_button/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/add_timeline_button/index.tsx index 5c4c7a38b130e..7aa9b01e8972b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/add_timeline_button/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/add_timeline_button/index.tsx @@ -55,6 +55,7 @@ const AddTimelineButtonComponent: React.FC = ({ id="timelineSettingsPopover" isOpen={showActions} closePopover={onClosePopover} + ownFocus repositionOnScroll > diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/bottom_bar/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/bottom_bar/index.tsx index edc571528e94a..d460d2c7b83d2 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/bottom_bar/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/bottom_bar/index.tsx @@ -13,11 +13,10 @@ import { IS_DRAGGING_CLASS_NAME } from '../../../../common/components/drag_and_d import { DataProvider } from '../../timeline/data_providers/data_provider'; import { flattenIntoAndGroups } from '../../timeline/data_providers/helpers'; import { DataProviders } from '../../timeline/data_providers'; +import { FLYOUT_BUTTON_BAR_CLASS_NAME, FLYOUT_BUTTON_CLASS_NAME } from '../../timeline/helpers'; import { FlyoutHeaderPanel } from '../header'; import { TimelineTabs } from '../../../../../common/types/timeline'; -export const FLYOUT_BUTTON_CLASS_NAME = 'timeline-flyout-button'; - export const getBadgeCount = (dataProviders: DataProvider[]): number => flattenIntoAndGroups(dataProviders).reduce((total, group) => total + group.length, 0); @@ -76,7 +75,11 @@ interface FlyoutBottomBarProps { export const FlyoutBottomBar = React.memo( ({ activeTab, showDataproviders, timelineId }) => { return ( - + {showDataproviders && } {(showDataproviders || (!showDataproviders && activeTab !== TimelineTabs.query)) && ( diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/header/active_timelines.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/header/active_timelines.tsx index ba24a1402adb0..1dbd201d763af 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/header/active_timelines.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/header/active_timelines.tsx @@ -13,6 +13,10 @@ import { FormattedRelative } from '@kbn/i18n/react'; import { TimelineStatus, TimelineType } from '../../../../../common/types/timeline'; import { TimelineEventsCountBadge } from '../../../../common/hooks/use_timeline_events_count'; +import { + ACTIVE_TIMELINE_BUTTON_CLASS_NAME, + focusActiveTimelineButton, +} from '../../timeline/helpers'; import { UNTITLED_TIMELINE, UNTITLED_TEMPLATE } from '../../timeline/properties/translations'; import { timelineActions } from '../../../store/timeline'; import * as i18n from './translations'; @@ -50,11 +54,10 @@ const ActiveTimelinesComponent: React.FC = ({ isOpen, }) => { const dispatch = useDispatch(); - - const handleToggleOpen = useCallback( - () => dispatch(timelineActions.showTimeline({ id: timelineId, show: !isOpen })), - [dispatch, isOpen, timelineId] - ); + const handleToggleOpen = useCallback(() => { + dispatch(timelineActions.showTimeline({ id: timelineId, show: !isOpen })); + focusActiveTimelineButton(); + }, [dispatch, isOpen, timelineId]); const title = !isEmpty(timelineTitle) ? timelineTitle @@ -83,6 +86,7 @@ const ActiveTimelinesComponent: React.FC = ({ = ({ timeline [dataProviders, kqlQuery] ); - const handleClose = useCallback( - () => dispatch(timelineActions.showTimeline({ id: timelineId, show: false })), - [dispatch, timelineId] - ); + const handleClose = useCallback(() => { + dispatch(timelineActions.showTimeline({ id: timelineId, show: false })); + focusActiveTimelineButton(); + }, [dispatch, timelineId]); return ( = ({ timelineId }) => { const dispatch = useDispatch(); - const handleClose = useCallback( - () => dispatch(timelineActions.showTimeline({ id: timelineId, show: false })), - [dispatch, timelineId] - ); + const handleClose = useCallback(() => { + dispatch(timelineActions.showTimeline({ id: timelineId, show: false })); + focusActiveTimelineButton(); + }, [dispatch, timelineId]); return ( diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/index.tsx index 2ded93377de93..ea68fc0a2a5da 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/index.tsx @@ -17,18 +17,17 @@ import { EuiButton, EuiFlexGroup, EuiFlexItem, - EuiInMemoryTable, } from '@elastic/eui'; -import React, { useState, useCallback, useMemo, useRef } from 'react'; +import React, { useState, useCallback, useMemo } from 'react'; import { useDispatch } from 'react-redux'; import styled from 'styled-components'; import { State } from '../../../common/store'; +import { RowRendererId } from '../../../../common/types/timeline'; import { useDeepEqualSelector } from '../../../common/hooks/use_selector'; import { setExcludedRowRendererIds as dispatchSetExcludedRowRendererIds } from '../../store/timeline/actions'; import { timelineSelectors } from '../../store/timeline'; import { timelineDefaults } from '../../store/timeline/defaults'; -import { renderers } from './catalog'; import { RowRenderersBrowser } from './row_renderers_browser'; import * as i18n from './translations'; @@ -81,7 +80,6 @@ interface StatefulRowRenderersBrowserProps { const StatefulRowRenderersBrowserComponent: React.FC = ({ timelineId, }) => { - const tableRef = useRef>(); const dispatch = useDispatch(); const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []); const excludedRowRendererIds = useDeepEqualSelector( @@ -105,12 +103,12 @@ const StatefulRowRenderersBrowserComponent: React.FC setShow(false), []); const handleDisableAll = useCallback(() => { - tableRef?.current?.setSelection([]); - }, [tableRef]); + setExcludedRowRendererIds(Object.values(RowRendererId)); + }, [setExcludedRowRendererIds]); const handleEnableAll = useCallback(() => { - tableRef?.current?.setSelection(renderers); - }, [tableRef]); + setExcludedRowRendererIds([]); + }, [setExcludedRowRendererIds]); return ( <> @@ -168,7 +166,6 @@ const StatefulRowRenderersBrowserComponent: React.FC diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/row_renderers_browser.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/row_renderers_browser.tsx index f1414724e243f..ca5aa36b597d0 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/row_renderers_browser.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/row_renderers_browser.tsx @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiFlexItem, EuiInMemoryTable } from '@elastic/eui'; +import { EuiCheckbox, EuiFlexItem, EuiInMemoryTable } from '@elastic/eui'; import React, { useMemo, useCallback } from 'react'; -import { xor, xorBy } from 'lodash/fp'; +import { xor } from 'lodash/fp'; import styled from 'styled-components'; import { RowRendererId } from '../../../../common/types/timeline'; @@ -76,101 +76,89 @@ const StyledNameButton = styled.button` text-align: left; `; -const RowRenderersBrowserComponent = React.forwardRef( - ({ excludedRowRendererIds = [], setExcludedRowRendererIds }: RowRenderersBrowserProps, ref) => { - const notExcludedRowRenderers = useMemo(() => { - if (excludedRowRendererIds.length === Object.keys(RowRendererId).length) return []; +const RowRenderersBrowserComponent = ({ + excludedRowRendererIds = [], + setExcludedRowRendererIds, +}: RowRenderersBrowserProps) => { + const handleNameClick = useCallback( + (item: RowRendererOption) => () => { + const newSelection = xor([item.id], excludedRowRendererIds); + + setExcludedRowRendererIds(newSelection); + }, + [excludedRowRendererIds, setExcludedRowRendererIds] + ); + + const nameColumnRenderCallback = useCallback( + (value, item) => ( + + {value} + + ), + [handleNameClick] + ); - return renderers.filter((renderer) => !excludedRowRendererIds.includes(renderer.id)); - }, [excludedRowRendererIds]); + const idColumnRenderCallback = useCallback( + (_, item) => ( + + ), + [excludedRowRendererIds, handleNameClick] + ); - const handleNameClick = useCallback( - (item: RowRendererOption) => () => { - const newSelection = xor([item], notExcludedRowRenderers); - // @ts-expect-error - ref?.current?.setSelection(newSelection); + const columns = useMemo( + () => [ + { + field: 'id', + name: '', + sortable: false, + width: '32px', + render: idColumnRenderCallback, }, - [notExcludedRowRenderers, ref] - ); - - const nameColumnRenderCallback = useCallback( - (value, item) => ( - - {value} - - ), - [handleNameClick] - ); - - const columns = useMemo( - () => [ - { - field: 'name', - name: 'Name', - sortable: true, - width: '10%', - render: nameColumnRenderCallback, - }, - { - field: 'description', - name: 'Description', - width: '25%', - render: (description: React.ReactNode) => description, - }, - { - field: 'example', - name: 'Example', - width: '65%', - render: ExampleWrapperComponent, - }, - { - field: 'searchableDescription', - name: 'Searchable Description', - sortable: false, - width: '0px', - render: renderSearchableDescriptionNoop, - }, - ], - [nameColumnRenderCallback] - ); - - const handleSelectable = useCallback(() => true, []); - - const handleSelectionChange = useCallback( - (selection: RowRendererOption[]) => { - if (!selection || !selection.length) - return setExcludedRowRendererIds(Object.values(RowRendererId)); - - const excludedRowRenderers = xorBy('id', renderers, selection); - - setExcludedRowRendererIds(excludedRowRenderers.map((rowRenderer) => rowRenderer.id)); + { + field: 'name', + name: 'Name', + sortable: true, + width: '10%', + render: nameColumnRenderCallback, }, - [setExcludedRowRendererIds] - ); - - const selectionValue = useMemo( - () => ({ - selectable: handleSelectable, - onSelectionChange: handleSelectionChange, - initialSelected: notExcludedRowRenderers, - }), - [handleSelectable, handleSelectionChange, notExcludedRowRenderers] - ); - - return ( - - ); - } -); + { + field: 'description', + name: 'Description', + width: '25%', + render: (description: React.ReactNode) => description, + }, + { + field: 'example', + name: 'Example', + width: '65%', + render: ExampleWrapperComponent, + }, + { + field: 'searchableDescription', + name: 'Searchable Description', + sortable: false, + width: '0px', + render: renderSearchableDescriptionNoop, + }, + ], + [idColumnRenderCallback, nameColumnRenderCallback] + ); + + return ( + + ); +}; RowRenderersBrowserComponent.displayName = 'RowRenderersBrowserComponent'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/__snapshots__/index.test.tsx.snap index 695032d80f8a0..83e783d97e40c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/__snapshots__/index.test.tsx.snap @@ -474,6 +474,7 @@ exports[`ColumnHeaders rendering renders correctly against snapshot 1`] = ` }, ] } + tabType="query" timelineId="test" /> `; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/column_header.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/column_header.tsx index 440f36cb465c5..c067c200bf460 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/column_header.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/column_header.tsx @@ -4,19 +4,23 @@ * you may not use this file except in compliance with the Elastic License. */ +import { EuiContextMenu, EuiContextMenuPanelDescriptor, EuiIcon, EuiPopover } from '@elastic/eui'; import React, { useCallback, useMemo, useRef, useState } from 'react'; import { Draggable } from 'react-beautiful-dnd'; import { Resizable, ResizeCallback } from 're-resizable'; import deepEqual from 'fast-deep-equal'; import { useDispatch } from 'react-redux'; +import styled from 'styled-components'; import { useDraggableKeyboardWrapper } from '../../../../../common/components/drag_and_drop/draggable_keyboard_wrapper_hook'; import { DRAGGABLE_KEYBOARD_WRAPPER_CLASS_NAME, getDraggableFieldId, } from '../../../../../common/components/drag_and_drop/helpers'; +import { TimelineTabs } from '../../../../../../common/types/timeline'; import { ColumnHeaderOptions } from '../../../../../timelines/store/timeline/model'; import { OnFilterChange } from '../../events'; +import { Direction } from '../../../../../graphql/types'; import { ARIA_COLUMN_INDEX_OFFSET } from '../../helpers'; import { EventsTh, EventsThContent, EventsHeadingHandle } from '../../styles'; import { Sort } from '../sort'; @@ -24,6 +28,25 @@ import { Sort } from '../sort'; import { Header } from './header'; import { timelineActions } from '../../../../store/timeline'; +import * as i18n from './translations'; + +const ContextMenu = styled(EuiContextMenu)` + width: 115px; + + & .euiContextMenuItem { + font-size: 12px; + padding: 4px 8px; + width: 115px; + } +`; + +const PopoverContainer = styled.div<{ $width: number }>` + & .euiPopover__anchor { + padding-right: 8px; + width: ${({ $width }) => $width}px; + } +`; + const RESIZABLE_ENABLE = { right: true }; interface ColumneHeaderProps { @@ -32,6 +55,7 @@ interface ColumneHeaderProps { isDragging: boolean; onFilterChange?: OnFilterChange; sort: Sort[]; + tabType: TimelineTabs; timelineId: string; } @@ -42,10 +66,11 @@ const ColumnHeaderComponent: React.FC = ({ isDragging, onFilterChange, sort, + tabType, }) => { const keyboardHandlerRef = useRef(null); - const [, setClosePopOverTrigger] = useState(false); - const [, setHoverActionsOwnFocus] = useState(false); + const [hoverActionsOwnFocus, setHoverActionsOwnFocus] = useState(false); + const restoreFocus = useCallback(() => keyboardHandlerRef.current?.focus(), []); const dispatch = useDispatch(); const resizableSize = useMemo( @@ -84,10 +109,93 @@ const ColumnHeaderComponent: React.FC = ({ const draggableId = useMemo( () => getDraggableFieldId({ - contextId: `timeline-column-headers-${timelineId}`, + contextId: `timeline-column-headers-${tabType}-${timelineId}`, fieldId: header.id, }), - [timelineId, header.id] + [tabType, timelineId, header.id] + ); + + const onColumnSort = useCallback( + (sortDirection: Direction) => { + const columnId = header.id; + const headerIndex = sort.findIndex((col) => col.columnId === columnId); + const newSort = + headerIndex === -1 + ? [ + ...sort, + { + columnId, + columnType: `${header.type}`, + sortDirection, + }, + ] + : [ + ...sort.slice(0, headerIndex), + { + columnId, + columnType: `${header.type}`, + sortDirection, + }, + ...sort.slice(headerIndex + 1), + ]; + + dispatch( + timelineActions.updateSort({ + id: timelineId, + sort: newSort, + }) + ); + }, + [dispatch, header, sort, timelineId] + ); + + const handleClosePopOverTrigger = useCallback(() => { + setHoverActionsOwnFocus(false); + restoreFocus(); + }, [restoreFocus]); + + const panels: EuiContextMenuPanelDescriptor[] = useMemo( + () => [ + { + id: 0, + items: [ + { + icon: , + name: i18n.HIDE_COLUMN, + onClick: () => { + dispatch(timelineActions.removeColumn({ id: timelineId, columnId: header.id })); + handleClosePopOverTrigger(); + }, + }, + { + disabled: !header.aggregatable, + icon: , + name: i18n.SORT_AZ, + onClick: () => { + onColumnSort(Direction.asc); + handleClosePopOverTrigger(); + }, + }, + { + disabled: !header.aggregatable, + icon: , + name: i18n.SORT_ZA, + onClick: () => { + onColumnSort(Direction.desc); + handleClosePopOverTrigger(); + }, + }, + ], + }, + ], + [dispatch, handleClosePopOverTrigger, header.aggregatable, header.id, onColumnSort, timelineId] + ); + + const headerButton = useMemo( + () => ( +
+ ), + [header, onFilterChange, sort, timelineId] ); const DraggableContent = useCallback( @@ -99,26 +207,28 @@ const ColumnHeaderComponent: React.FC = ({ ref={dragProvided.innerRef} > -
+ + + + + ), - [header, onFilterChange, sort, timelineId] + [handleClosePopOverTrigger, headerButton, header.width, hoverActionsOwnFocus, panels] ); const onFocus = useCallback(() => { keyboardHandlerRef.current?.focus(); }, []); - const handleClosePopOverTrigger = useCallback(() => { - setClosePopOverTrigger((prevClosePopOverTrigger) => !prevClosePopOverTrigger); - }, []); - const openPopover = useCallback(() => { setHoverActionsOwnFocus(true); }, []); @@ -131,6 +241,15 @@ const ColumnHeaderComponent: React.FC = ({ openPopover, }); + const keyDownHandler = useCallback( + (keyboardEvent: React.KeyboardEvent) => { + if (!hoverActionsOwnFocus) { + onKeyDown(keyboardEvent); + } + }, + [hoverActionsOwnFocus, onKeyDown] + ); + return ( = ({ data-test-subj="draggableWrapperKeyboardHandler" onClick={onFocus} onBlur={onBlur} - onKeyDown={onKeyDown} + onKeyDown={keyDownHandler} ref={keyboardHandlerRef} role="columnheader" tabIndex={0} @@ -171,6 +290,7 @@ export const ColumnHeader = React.memo( ColumnHeaderComponent, (prevProps, nextProps) => prevProps.draggableIndex === nextProps.draggableIndex && + prevProps.tabType === nextProps.tabType && prevProps.timelineId === nextProps.timelineId && prevProps.isDragging === nextProps.isDragging && prevProps.onFilterChange === nextProps.onFilterChange && diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.test.tsx index 307166388b494..22a450ac29268 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.test.tsx @@ -19,6 +19,7 @@ import { useMountAppended } from '../../../../../common/utils/use_mount_appended import { ColumnHeadersComponent } from '.'; import { cloneDeep } from 'lodash/fp'; import { timelineActions } from '../../../../store/timeline'; +import { TimelineTabs } from '../../../../../../common/types/timeline'; const mockDispatch = jest.fn(); jest.mock('react-redux', () => { @@ -55,6 +56,7 @@ describe('ColumnHeaders', () => { showEventsSelect={false} showSelectAllCheckbox={false} sort={sort} + tabType={TimelineTabs.query} timelineId={timelineId} /> @@ -74,6 +76,7 @@ describe('ColumnHeaders', () => { showEventsSelect={false} showSelectAllCheckbox={false} sort={sort} + tabType={TimelineTabs.query} timelineId={timelineId} /> @@ -94,6 +97,7 @@ describe('ColumnHeaders', () => { showEventsSelect={false} showSelectAllCheckbox={false} sort={sort} + tabType={TimelineTabs.query} timelineId={timelineId} /> @@ -152,6 +156,7 @@ describe('ColumnHeaders', () => { showEventsSelect={false} showSelectAllCheckbox={false} sort={mockSort} + tabType={TimelineTabs.query} timelineId={timelineId} /> @@ -193,6 +198,7 @@ describe('ColumnHeaders', () => { showEventsSelect={false} showSelectAllCheckbox={false} sort={mockSort} + tabType={TimelineTabs.query} timelineId={timelineId} /> @@ -229,6 +235,7 @@ describe('ColumnHeaders', () => { showEventsSelect={false} showSelectAllCheckbox={false} sort={mockSort} + tabType={TimelineTabs.query} timelineId={timelineId} /> diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx index 21f32a211f42c..a6dd88553529a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx @@ -31,7 +31,7 @@ import { useGlobalFullScreen, useTimelineFullScreen, } from '../../../../../common/containers/use_full_screen'; -import { TimelineId } from '../../../../../../common/types/timeline'; +import { TimelineId, TimelineTabs } from '../../../../../../common/types/timeline'; import { OnSelectAll } from '../../events'; import { DEFAULT_ICON_BUTTON_WIDTH } from '../../helpers'; import { StatefulFieldsBrowser } from '../../../fields_browser'; @@ -76,6 +76,7 @@ interface Props { showEventsSelect: boolean; showSelectAllCheckbox: boolean; sort: Sort[]; + tabType: TimelineTabs; timelineId: string; } @@ -122,6 +123,7 @@ export const ColumnHeadersComponent = ({ showEventsSelect, showSelectAllCheckbox, sort, + tabType, timelineId, }: Props) => { const dispatch = useDispatch(); @@ -186,9 +188,10 @@ export const ColumnHeadersComponent = ({ header={header} isDragging={draggingIndex === draggableIndex} sort={sort} + tabType={tabType} /> )), - [columnHeaders, timelineId, draggingIndex, sort] + [columnHeaders, timelineId, draggingIndex, sort, tabType] ); const fullScreen = useMemo( @@ -335,7 +338,7 @@ export const ColumnHeadersComponent = ({ ( showEventsSelect={false} showSelectAllCheckbox={showCheckboxes} sort={sort} + tabType={tabType} timelineId={id} /> diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/__snapshots__/provider.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/__snapshots__/provider.test.tsx.snap index d589a9aa33f06..acc48bdc6c044 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/__snapshots__/provider.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/__snapshots__/provider.test.tsx.snap @@ -6,9 +6,11 @@ exports[`Provider rendering renders correctly against snapshot 1`] = ` field="name" isEnabled={true} isExcluded={false} + isPopoverOpen={false} kqlQuery="" operator=":" providerId="id-Provider 1" + setIsPopoverOpen={[Function]} toggleEnabledProvider={[Function]} toggleExcludedProvider={[Function]} toggleTypeProvider={[Function]} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider.tsx index 2b598c7cf04f0..0c52ec6ab41c1 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider.tsx @@ -5,7 +5,7 @@ */ import { noop } from 'lodash/fp'; -import React from 'react'; +import React, { useState } from 'react'; import { DataProvider, DataProviderType, IS_OPERATOR } from './data_provider'; import { ProviderItemBadge } from './provider_item_badge'; @@ -14,21 +14,27 @@ interface OwnProps { dataProvider: DataProvider; } -export const Provider = React.memo(({ dataProvider }) => ( - -)); +export const Provider = React.memo(({ dataProvider }) => { + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + + return ( + + ); +}); Provider.displayName = 'Provider'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_actions.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_actions.tsx index 7aa782c05c0dd..a9808ee9c8003 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_actions.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_actions.tsx @@ -231,6 +231,7 @@ export class ProviderItemActions extends React.PureComponent { button={button} anchorPosition="downCenter" panelPaddingSize="none" + ownFocus={true} >
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_badge.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_badge.tsx index 866c07fd2fcc1..db6051043e248 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_badge.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_badge.tsx @@ -28,10 +28,12 @@ interface ProviderItemBadgeProps { kqlQuery: string; isEnabled: boolean; isExcluded: boolean; + isPopoverOpen: boolean; onDataProviderEdited?: OnDataProviderEdited; operator: QueryOperator; providerId: string; register?: DataProvidersAnd; + setIsPopoverOpen: (isPopoverOpen: boolean) => void; timelineId?: string; toggleEnabledProvider: () => void; toggleExcludedProvider: () => void; @@ -50,10 +52,12 @@ export const ProviderItemBadge = React.memo( kqlQuery, isEnabled, isExcluded, + isPopoverOpen, onDataProviderEdited, operator, providerId, register, + setIsPopoverOpen, timelineId, toggleEnabledProvider, toggleExcludedProvider, @@ -75,16 +79,15 @@ export const ProviderItemBadge = React.memo( getManageTimelineById, timelineId, ]); - const [isPopoverOpen, setIsPopoverOpen] = useState(false); const togglePopover = useCallback(() => { setIsPopoverOpen(!isPopoverOpen); - }, [isPopoverOpen]); + }, [isPopoverOpen, setIsPopoverOpen]); const closePopover = useCallback(() => { setIsPopoverOpen(false); wrapperRef?.current?.focus(); - }, [wrapperRef]); + }, [wrapperRef, setIsPopoverOpen]); const onToggleEnabledProvider = useCallback(() => { toggleEnabledProvider(); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.tsx index d01edebda60e6..2f61756b97c60 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.tsx @@ -155,7 +155,7 @@ interface DataProvidersGroupItem extends Omit { export const DataProvidersGroupItem = React.memo( ({ browserFields, group, groupIndex, dataProvider, index, timelineId }) => { const keyboardHandlerRef = useRef(null); - const [, setHoverActionsOwnFocus] = useState(false); + const [isPopoverOpen, setIsPopoverOpen] = useState(false); const [, setClosePopOverTrigger] = useState(false); const dispatch = useDispatch(); @@ -240,7 +240,7 @@ export const DataProvidersGroupItem = React.memo( }, []); const openPopover = useCallback(() => { - setHoverActionsOwnFocus(true); + setIsPopoverOpen(true); }, []); const { onBlur, onKeyDown } = useDraggableKeyboardWrapper({ @@ -251,6 +251,15 @@ export const DataProvidersGroupItem = React.memo( openPopover, }); + const keyDownHandler = useCallback( + (keyboardEvent: React.KeyboardEvent) => { + if (keyboardHandlerRef.current === document.activeElement) { + onKeyDown(keyboardEvent); + } + }, + [onKeyDown] + ); + const DraggableContent = useCallback( (provided, snapshot) => (
( kqlQuery={index > 0 ? dataProvider.kqlQuery : group[0].kqlQuery} isEnabled={index > 0 ? dataProvider.enabled : group[0].enabled} isExcluded={index > 0 ? dataProvider.excluded : group[0].excluded} + isPopoverOpen={isPopoverOpen} onDataProviderEdited={handleDataProviderEdited} operator={ index > 0 @@ -284,6 +294,7 @@ export const DataProvidersGroupItem = React.memo( register={dataProvider} providerId={index > 0 ? group[0].id : dataProvider.id} timelineId={timelineId} + setIsPopoverOpen={setIsPopoverOpen} toggleEnabledProvider={handleToggleEnabledProvider} toggleExcludedProvider={handleToggleExcludedProvider} toggleTypeProvider={handleToggleTypeProvider} @@ -315,7 +326,9 @@ export const DataProvidersGroupItem = React.memo( handleToggleExcludedProvider, handleToggleTypeProvider, index, + isPopoverOpen, keyboardHandlerRef, + setIsPopoverOpen, timelineId, ] ); @@ -326,7 +339,7 @@ export const DataProvidersGroupItem = React.memo( data-test-subj="draggableWrapperKeyboardHandler" onClick={onFocus} onBlur={onBlur} - onKeyDown={onKeyDown} + onKeyDown={keyDownHandler} ref={keyboardHandlerRef} role="button" tabIndex={0} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx index 02b3d0673a5a9..f261d9ed60c6e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx @@ -242,3 +242,40 @@ export const onTimelineTabKeyPressed = ({ }); } }; + +export const ACTIVE_TIMELINE_BUTTON_CLASS_NAME = 'active-timeline-button'; +export const FLYOUT_BUTTON_BAR_CLASS_NAME = 'timeline-flyout-button-bar'; +export const FLYOUT_BUTTON_CLASS_NAME = 'timeline-flyout-button'; + +/** + * This function focuses the active timeline button on the next tick. Focus + * is updated on the next tick because this function is typically + * invoked in `onClick` handlers that also dispatch Redux actions (that + * in-turn update focus states). + */ +export const focusActiveTimelineButton = () => { + setTimeout(() => { + document + .querySelector( + `div.${FLYOUT_BUTTON_BAR_CLASS_NAME} .${ACTIVE_TIMELINE_BUTTON_CLASS_NAME}` + ) + ?.focus(); + }, 0); +}; + +/** + * Focuses the utility bar action contained by the provided `containerElement` + * when a valid container is provided + */ +export const focusUtilityBarAction = (containerElement: HTMLElement | null) => { + containerElement + ?.querySelector('div.siemUtilityBar__action:last-of-type button') + ?.focus(); +}; + +/** + * Resets keyboard focus on the page + */ +export const resetKeyboardFocus = () => { + document.querySelector('header.headerGlobalNav a.euiHeaderLogo')?.focus(); +}; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/styles.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/styles.tsx index d86f0a936376f..a81318ee95eda 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/styles.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/styles.tsx @@ -432,6 +432,7 @@ export const EventsHeadingHandle = styled.div.attrs(({ className = '' }) => ({ */ export const EventsLoading = styled(EuiLoadingSpinner)` + margin: 0 2px; vertical-align: middle; `; From 7451288a8144cfe69ebe2c84a836905005e4b034 Mon Sep 17 00:00:00 2001 From: Alexey Antonov Date: Tue, 12 Jan 2021 12:35:54 +0300 Subject: [PATCH 28/64] Remove src/plugins/visualizations -> src/plugins/visualize cyclic dependencies (#87797) * Remove src/plugins/visualizations -> src/plugins/visualize cyclic dependencies Part of #84750 * fix types --- .../run_find_plugins_with_circular_deps.ts | 1 - .../public/default_editor.tsx | 7 ++- .../public/default_editor_controller.tsx | 8 +++- src/plugins/visualizations/public/index.ts | 3 ++ .../visualizations/public/vis_types/index.ts | 9 +++- .../visualizations/public/vis_types/types.ts | 43 +++++++++++++++++-- .../visualize/public/application/types.ts | 30 +------------ .../utils/use/use_editor_updates.test.ts | 8 +--- .../utils/use/use_editor_updates.ts | 2 +- .../utils/use/use_saved_vis_instance.ts | 3 +- .../application/utils/use/use_vis_byvalue.ts | 3 +- src/plugins/visualize/public/index.ts | 5 --- src/plugins/visualize/public/plugin.ts | 4 +- src/plugins/visualize/public/services.ts | 2 +- 14 files changed, 73 insertions(+), 55 deletions(-) diff --git a/src/dev/run_find_plugins_with_circular_deps.ts b/src/dev/run_find_plugins_with_circular_deps.ts index 75faf3d8c17a7..fc599ad738dfa 100644 --- a/src/dev/run_find_plugins_with_circular_deps.ts +++ b/src/dev/run_find_plugins_with_circular_deps.ts @@ -31,7 +31,6 @@ interface Options { type CircularDepList = Set; const allowedList: CircularDepList = new Set([ - 'src/plugins/visualizations -> src/plugins/visualize', 'x-pack/plugins/actions -> x-pack/plugins/case', 'x-pack/plugins/case -> x-pack/plugins/security_solution', 'x-pack/plugins/apm -> x-pack/plugins/infra', diff --git a/src/plugins/vis_default_editor/public/default_editor.tsx b/src/plugins/vis_default_editor/public/default_editor.tsx index a7251acfdf75d..719766544d4f2 100644 --- a/src/plugins/vis_default_editor/public/default_editor.tsx +++ b/src/plugins/vis_default_editor/public/default_editor.tsx @@ -23,8 +23,11 @@ import 'brace/mode/json'; import React, { useEffect, useRef, useState, useCallback } from 'react'; import { EventEmitter } from 'events'; -import { EditorRenderProps } from 'src/plugins/visualize/public'; -import { Vis, VisualizeEmbeddableContract } from 'src/plugins/visualizations/public'; +import { + Vis, + VisualizeEmbeddableContract, + EditorRenderProps, +} from 'src/plugins/visualizations/public'; import { KibanaContextProvider, PanelsContainer, Panel } from '../../kibana_react/public'; import { Storage } from '../../kibana_utils/public'; diff --git a/src/plugins/vis_default_editor/public/default_editor_controller.tsx b/src/plugins/vis_default_editor/public/default_editor_controller.tsx index f44ea3e203b05..ebeb056cc89c1 100644 --- a/src/plugins/vis_default_editor/public/default_editor_controller.tsx +++ b/src/plugins/vis_default_editor/public/default_editor_controller.tsx @@ -22,8 +22,12 @@ import { render, unmountComponentAtNode } from 'react-dom'; import { EventEmitter } from 'events'; import { EuiErrorBoundary, EuiLoadingChart } from '@elastic/eui'; -import { EditorRenderProps, IEditorController } from 'src/plugins/visualize/public'; -import { Vis, VisualizeEmbeddableContract } from 'src/plugins/visualizations/public'; +import { + Vis, + IEditorController, + EditorRenderProps, + VisualizeEmbeddableContract, +} from 'src/plugins/visualizations/public'; // @ts-ignore const DefaultEditor = lazy(() => import('./default_editor')); diff --git a/src/plugins/visualizations/public/index.ts b/src/plugins/visualizations/public/index.ts index 854e04325b078..ad56f6a34c368 100644 --- a/src/plugins/visualizations/public/index.ts +++ b/src/plugins/visualizations/public/index.ts @@ -44,6 +44,9 @@ export type { ReactVisTypeOptions, Schema, ISchemas, + VisEditorConstructor, + IEditorController, + EditorRenderProps, } from './vis_types'; export { VisParams, SerializedVis, SerializedVisData, VisData } from './vis'; export type VisualizeEmbeddableFactoryContract = PublicContract; diff --git a/src/plugins/visualizations/public/vis_types/index.ts b/src/plugins/visualizations/public/vis_types/index.ts index 43de5d1ecce53..68c613f11f8df 100644 --- a/src/plugins/visualizations/public/vis_types/index.ts +++ b/src/plugins/visualizations/public/vis_types/index.ts @@ -20,6 +20,13 @@ export * from './types_service'; export { Schemas } from './schemas'; export { VisGroups } from './types'; -export type { VisType, ISchemas, Schema } from './types'; +export type { + VisType, + ISchemas, + Schema, + IEditorController, + VisEditorConstructor, + EditorRenderProps, +} from './types'; export type { BaseVisTypeOptions } from './base_vis_type'; export type { ReactVisTypeOptions } from './react_vis_type'; diff --git a/src/plugins/visualizations/public/vis_types/types.ts b/src/plugins/visualizations/public/vis_types/types.ts index 88a4dad106897..c51c2415af041 100644 --- a/src/plugins/visualizations/public/vis_types/types.ts +++ b/src/plugins/visualizations/public/vis_types/types.ts @@ -16,13 +16,24 @@ * specific language governing permissions and limitations * under the License. */ - +import { EventEmitter } from 'events'; import { IconType } from '@elastic/eui'; import React, { ReactNode } from 'react'; import { Adapters } from 'src/plugins/inspector'; -import { VisEditorConstructor } from 'src/plugins/visualize/public'; -import { IndexPattern, AggGroupNames, AggParam, AggGroupName } from '../../../data/public'; +import { CoreStart } from 'src/core/public'; +import { SavedObject } from 'src/plugins/saved_objects/public'; +import { + IndexPattern, + AggGroupNames, + AggParam, + AggGroupName, + DataPublicPluginStart, + Filter, + TimeRange, + Query, +} from '../../../data/public'; import { Vis, VisParams, VisToExpressionAst, VisualizationControllerConstructor } from '../types'; +import { PersistedState, VisualizeEmbeddableContract } from '../index'; export interface VisTypeOptions { showTimePicker: boolean; @@ -152,3 +163,29 @@ export interface VisType { readonly editorConfig: Record; readonly visConfig: Record; } + +export type VisEditorConstructor = new ( + element: HTMLElement, + vis: Vis, + eventEmitter: EventEmitter, + embeddableHandler: VisualizeEmbeddableContract +) => IEditorController; + +export interface IEditorController { + render(props: EditorRenderProps): Promise | void; + destroy(): void; +} + +export interface EditorRenderProps { + core: CoreStart; + data: DataPublicPluginStart; + filters: Filter[]; + timeRange: TimeRange; + query?: Query; + savedSearch?: SavedObject; + uiState: PersistedState; + /** + * Flag to determine if visualiztion is linked to the saved search + */ + linked: boolean; +} diff --git a/src/plugins/visualize/public/application/types.ts b/src/plugins/visualize/public/application/types.ts index 1729d273e24bc..78727492ac012 100644 --- a/src/plugins/visualize/public/application/types.ts +++ b/src/plugins/visualize/public/application/types.ts @@ -18,9 +18,8 @@ */ import { History } from 'history'; -import { TimeRange, Query, Filter, DataPublicPluginStart } from 'src/plugins/data/public'; +import { Query, Filter, DataPublicPluginStart } from 'src/plugins/data/public'; import { - PersistedState, SavedVisState, VisualizationsStart, Vis, @@ -45,7 +44,6 @@ import { SharePluginStart } from 'src/plugins/share/public'; import { SavedObjectsStart, SavedObject } from 'src/plugins/saved_objects/public'; import { EmbeddableStart, EmbeddableStateTransfer } from 'src/plugins/embeddable/public'; import { UrlForwardingStart } from 'src/plugins/url_forwarding/public'; -import { EventEmitter } from 'events'; import { DashboardStart } from '../../../dashboard/public'; import type { SavedObjectsTaggingApi } from '../../../saved_objects_tagging_oss/public'; @@ -80,20 +78,6 @@ export type VisualizeAppStateContainer = ReduxLikeStateContainer< VisualizeAppStateTransitions >; -export interface EditorRenderProps { - core: CoreStart; - data: DataPublicPluginStart; - filters: Filter[]; - timeRange: TimeRange; - query?: Query; - savedSearch?: SavedObject; - uiState: PersistedState; - /** - * Flag to determine if visualiztion is linked to the saved search - */ - linked: boolean; -} - export interface VisualizeServices extends CoreStart { stateTransferService: EmbeddableStateTransfer; embeddable: EmbeddableStart; @@ -135,15 +119,3 @@ export interface ByValueVisInstance { } export type VisualizeEditorVisInstance = SavedVisInstance | ByValueVisInstance; - -export type VisEditorConstructor = new ( - element: HTMLElement, - vis: Vis, - eventEmitter: EventEmitter, - embeddableHandler: VisualizeEmbeddableContract -) => IEditorController; - -export interface IEditorController { - render(props: EditorRenderProps): Promise | void; - destroy(): void; -} diff --git a/src/plugins/visualize/public/application/utils/use/use_editor_updates.test.ts b/src/plugins/visualize/public/application/utils/use/use_editor_updates.test.ts index 23894368d606c..c9ffc8c27a978 100644 --- a/src/plugins/visualize/public/application/utils/use/use_editor_updates.test.ts +++ b/src/plugins/visualize/public/application/utils/use/use_editor_updates.test.ts @@ -21,12 +21,8 @@ import { renderHook, act } from '@testing-library/react-hooks'; import { EventEmitter } from 'events'; import { useEditorUpdates } from './use_editor_updates'; -import { - VisualizeServices, - VisualizeAppStateContainer, - SavedVisInstance, - IEditorController, -} from '../../types'; +import { VisualizeServices, VisualizeAppStateContainer, SavedVisInstance } from '../../types'; +import type { IEditorController } from '../../../../../visualizations/public'; import { visualizeAppStateStub } from '../stubs'; import { createVisualizeServicesMock } from '../mocks'; diff --git a/src/plugins/visualize/public/application/utils/use/use_editor_updates.ts b/src/plugins/visualize/public/application/utils/use/use_editor_updates.ts index c29f6337a6246..1edb5564b48a7 100644 --- a/src/plugins/visualize/public/application/utils/use/use_editor_updates.ts +++ b/src/plugins/visualize/public/application/utils/use/use_editor_updates.ts @@ -25,9 +25,9 @@ import { VisualizeServices, VisualizeAppState, VisualizeAppStateContainer, - IEditorController, VisualizeEditorVisInstance, } from '../../types'; +import type { IEditorController } from '../../../../../visualizations/public'; export const useEditorUpdates = ( services: VisualizeServices, diff --git a/src/plugins/visualize/public/application/utils/use/use_saved_vis_instance.ts b/src/plugins/visualize/public/application/utils/use/use_saved_vis_instance.ts index 3f9b3ca9b8b73..a8d17a3cdfadb 100644 --- a/src/plugins/visualize/public/application/utils/use/use_saved_vis_instance.ts +++ b/src/plugins/visualize/public/application/utils/use/use_saved_vis_instance.ts @@ -26,9 +26,10 @@ import { redirectWhenMissing } from '../../../../../kibana_utils/public'; import { getVisualizationInstance } from '../get_visualization_instance'; import { getEditBreadcrumbs, getCreateBreadcrumbs } from '../breadcrumbs'; -import { SavedVisInstance, IEditorController, VisualizeServices } from '../../types'; +import { SavedVisInstance, VisualizeServices } from '../../types'; import { VisualizeConstants } from '../../visualize_constants'; import { getDefaultEditor } from '../../../services'; +import type { IEditorController } from '../../../../../visualizations/public'; /** * This effect is responsible for instantiating a saved vis or creating a new one diff --git a/src/plugins/visualize/public/application/utils/use/use_vis_byvalue.ts b/src/plugins/visualize/public/application/utils/use/use_vis_byvalue.ts index 9e222d208f460..6c9a464d64a72 100644 --- a/src/plugins/visualize/public/application/utils/use/use_vis_byvalue.ts +++ b/src/plugins/visualize/public/application/utils/use/use_vis_byvalue.ts @@ -20,7 +20,8 @@ import { EventEmitter } from 'events'; import { useEffect, useRef, useState } from 'react'; import { VisualizeInput } from 'src/plugins/visualizations/public'; -import { ByValueVisInstance, IEditorController, VisualizeServices } from '../../types'; +import { ByValueVisInstance, VisualizeServices } from '../../types'; +import type { IEditorController } from '../../../../../visualizations/public'; import { getVisualizationInstanceFromInput } from '../get_visualization_instance'; import { getEditBreadcrumbs } from '../breadcrumbs'; import { getDefaultEditor } from '../../../services'; diff --git a/src/plugins/visualize/public/index.ts b/src/plugins/visualize/public/index.ts index c9ac85c5123ce..385313f81ff68 100644 --- a/src/plugins/visualize/public/index.ts +++ b/src/plugins/visualize/public/index.ts @@ -20,11 +20,6 @@ import { PluginInitializerContext } from 'kibana/public'; import { VisualizePlugin, VisualizePluginSetup } from './plugin'; -export type { - EditorRenderProps, - IEditorController, - VisEditorConstructor, -} from './application/types'; export { VisualizeConstants } from './application/visualize_constants'; export { VisualizePluginSetup }; diff --git a/src/plugins/visualize/public/plugin.ts b/src/plugins/visualize/public/plugin.ts index 5eef58a336eab..b1507155316e2 100644 --- a/src/plugins/visualize/public/plugin.ts +++ b/src/plugins/visualize/public/plugin.ts @@ -41,10 +41,10 @@ import { DataPublicPluginStart, DataPublicPluginSetup, esFilters } from '../../d import { NavigationPublicPluginStart as NavigationStart } from '../../navigation/public'; import { SharePluginStart, SharePluginSetup } from '../../share/public'; import { UrlForwardingSetup, UrlForwardingStart } from '../../url_forwarding/public'; -import { VisualizationsStart } from '../../visualizations/public'; +import { VisualizationsStart, VisEditorConstructor } from '../../visualizations/public'; import { VisualizeConstants } from './application/visualize_constants'; import { FeatureCatalogueCategory, HomePublicPluginSetup } from '../../home/public'; -import { VisEditorConstructor, VisualizeServices } from './application/types'; +import { VisualizeServices } from './application/types'; import { DEFAULT_APP_CATEGORIES } from '../../../core/public'; import { SavedObjectsStart } from '../../saved_objects/public'; import { EmbeddableStart } from '../../embeddable/public'; diff --git a/src/plugins/visualize/public/services.ts b/src/plugins/visualize/public/services.ts index 7994ad14543d5..5a8ac00430fbf 100644 --- a/src/plugins/visualize/public/services.ts +++ b/src/plugins/visualize/public/services.ts @@ -20,8 +20,8 @@ import { ApplicationStart, IUiSettingsClient } from '../../../core/public'; import { createGetterSetter } from '../../../plugins/kibana_utils/public'; import { IndexPatternsContract, DataPublicPluginStart } from '../../../plugins/data/public'; +import { VisEditorConstructor } from '../../../plugins/visualizations/public'; import { SharePluginStart } from '../../../plugins/share/public'; -import { VisEditorConstructor } from './application/types'; export const [getUISettings, setUISettings] = createGetterSetter('UISettings'); From 94b02d97ed12c7d93081f88768def083b439473a Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Tue, 12 Jan 2021 10:45:53 +0100 Subject: [PATCH 29/64] [Lens] Implement deep linking and embedding (#84416) --- .../embedded_lens_example/.eslintrc.json | 5 + .../examples/embedded_lens_example/README.md | 13 ++ .../embedded_lens_example/kibana.json | 15 ++ .../embedded_lens_example/package.json | 14 ++ .../embedded_lens_example/public/app.tsx | 180 ++++++++++++++++++ .../embedded_lens_example/public/index.ts | 9 + .../embedded_lens_example/public/mount.tsx | 28 +++ .../embedded_lens_example/public/plugin.ts | 53 ++++++ .../embedded_lens_example/tsconfig.json | 22 +++ .../plugins/lens/public/app_plugin/types.ts | 2 +- .../embeddable/embeddable.test.tsx | 2 - .../embeddable/embeddable.tsx | 42 +++- .../embeddable/embeddable_component.tsx | 51 +++++ .../embeddable/expression_wrapper.tsx | 7 +- x-pack/plugins/lens/public/index.ts | 11 +- .../indexpattern_datasource/indexpattern.tsx | 2 +- .../metric_suggestions.test.ts | 2 +- x-pack/plugins/lens/public/plugin.ts | 61 +++++- .../lens/public/xy_visualization/types.ts | 2 +- 19 files changed, 506 insertions(+), 15 deletions(-) create mode 100644 x-pack/examples/embedded_lens_example/.eslintrc.json create mode 100644 x-pack/examples/embedded_lens_example/README.md create mode 100644 x-pack/examples/embedded_lens_example/kibana.json create mode 100644 x-pack/examples/embedded_lens_example/package.json create mode 100644 x-pack/examples/embedded_lens_example/public/app.tsx create mode 100644 x-pack/examples/embedded_lens_example/public/index.ts create mode 100644 x-pack/examples/embedded_lens_example/public/mount.tsx create mode 100644 x-pack/examples/embedded_lens_example/public/plugin.ts create mode 100644 x-pack/examples/embedded_lens_example/tsconfig.json create mode 100644 x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable_component.tsx diff --git a/x-pack/examples/embedded_lens_example/.eslintrc.json b/x-pack/examples/embedded_lens_example/.eslintrc.json new file mode 100644 index 0000000000000..2aab6c2d9093b --- /dev/null +++ b/x-pack/examples/embedded_lens_example/.eslintrc.json @@ -0,0 +1,5 @@ +{ + "rules": { + "@typescript-eslint/consistent-type-definitions": 0 + } +} diff --git a/x-pack/examples/embedded_lens_example/README.md b/x-pack/examples/embedded_lens_example/README.md new file mode 100644 index 0000000000000..ac9ba99569c6d --- /dev/null +++ b/x-pack/examples/embedded_lens_example/README.md @@ -0,0 +1,13 @@ +# Embedded Lens examples + +To run this example plugin, use the command `yarn start --run-examples`. + +This example shows how to embed Lens into other applications. Using the `EmbeddableComponent` of the `lens` start plugin, +you can pass in a valid Lens configuration which will get rendered the same way Lens dashboard panels work. Updating the +configuration will reload the embedded visualization. + +## Link to editor + +It is possible to use the same configuration and the `navigateToPrefilledEditor` method to navigate the current user to a +prefilled Lens editor so they can manipulate the configuration on their own and even save the results to a dashboard. +Make sure to always check permissions using `canUseEditor` whether the current user has permissions to access Lens. \ No newline at end of file diff --git a/x-pack/examples/embedded_lens_example/kibana.json b/x-pack/examples/embedded_lens_example/kibana.json new file mode 100644 index 0000000000000..5e4caead90bc3 --- /dev/null +++ b/x-pack/examples/embedded_lens_example/kibana.json @@ -0,0 +1,15 @@ +{ + "id": "embeddedLensExample", + "version": "0.0.1", + "kibanaVersion": "kibana", + "configPath": ["embedded_lens_example"], + "server": false, + "ui": true, + "requiredPlugins": [ + "lens", + "data", + "developerExamples" + ], + "optionalPlugins": [], + "requiredBundles": [] +} diff --git a/x-pack/examples/embedded_lens_example/package.json b/x-pack/examples/embedded_lens_example/package.json new file mode 100644 index 0000000000000..f66a0d5adba4e --- /dev/null +++ b/x-pack/examples/embedded_lens_example/package.json @@ -0,0 +1,14 @@ +{ + "name": "embedded_lens_example", + "version": "1.0.0", + "main": "target/examples/embedded_lens_example", + "kibana": { + "version": "kibana", + "templateVersion": "1.0.0" + }, + "license": "Apache-2.0", + "scripts": { + "kbn": "node ../../../scripts/kbn.js", + "build": "rm -rf './target' && ../../../node_modules/.bin/tsc" + } +} \ No newline at end of file diff --git a/x-pack/examples/embedded_lens_example/public/app.tsx b/x-pack/examples/embedded_lens_example/public/app.tsx new file mode 100644 index 0000000000000..9f35907ca335d --- /dev/null +++ b/x-pack/examples/embedded_lens_example/public/app.tsx @@ -0,0 +1,180 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useState } from 'react'; +import { + EuiButton, + EuiFlexGroup, + EuiFlexItem, + EuiPage, + EuiPageBody, + EuiPageContent, + EuiPageContentBody, + EuiPageHeader, + EuiPageHeaderSection, + EuiTitle, +} from '@elastic/eui'; +import { IndexPattern } from 'src/plugins/data/public'; +import { CoreStart } from 'kibana/public'; +import { TypedLensByValueInput } from '../../../plugins/lens/public'; +import { StartDependencies } from './plugin'; + +// Generate a Lens state based on some app-specific input parameters. +// `TypedLensByValueInput` can be used for type-safety - it uses the same interfaces as Lens-internal code. +function getLensAttributes( + defaultIndexPattern: IndexPattern, + color: string +): TypedLensByValueInput['attributes'] { + return { + visualizationType: 'lnsXY', + title: 'Prefilled from example app', + references: [ + { + id: defaultIndexPattern.id!, + name: 'indexpattern-datasource-current-indexpattern', + type: 'index-pattern', + }, + { + id: defaultIndexPattern.id!, + name: 'indexpattern-datasource-layer-layer1', + type: 'index-pattern', + }, + ], + state: { + datasourceStates: { + indexpattern: { + layers: { + layer1: { + columnOrder: ['col1', 'col2'], + columns: { + col2: { + dataType: 'number', + isBucketed: false, + label: 'Count of records', + operationType: 'count', + scale: 'ratio', + sourceField: 'Records', + }, + col1: { + dataType: 'date', + isBucketed: true, + label: '@timestamp', + operationType: 'date_histogram', + params: { interval: 'auto' }, + scale: 'interval', + sourceField: defaultIndexPattern.timeFieldName!, + }, + }, + }, + }, + }, + }, + filters: [], + query: { language: 'kuery', query: '' }, + visualization: { + axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, + fittingFunction: 'None', + gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, + layers: [ + { + accessors: ['col2'], + layerId: 'layer1', + seriesType: 'bar_stacked', + xAccessor: 'col1', + yConfig: [{ forAccessor: 'col2', color }], + }, + ], + legend: { isVisible: true, position: 'right' }, + preferredSeriesType: 'bar_stacked', + tickLabelsVisibilitySettings: { x: true, yLeft: true, yRight: true }, + valueLabels: 'hide', + }, + }, + }; +} + +export const App = (props: { + core: CoreStart; + plugins: StartDependencies; + defaultIndexPattern: IndexPattern | null; +}) => { + const [color, setColor] = useState('green'); + const LensComponent = props.plugins.lens.EmbeddableComponent; + return ( + + + + + +

Embedded Lens vis

+
+
+
+ + +

+ This app embeds a Lens visualization by specifying the configuration. Data fetching + and rendering is completely managed by Lens itself. +

+

+ The Change color button will update the configuration by picking a new random color of + the series which causes Lens to re-render. The Edit button will take the current + configuration and navigate to a prefilled editor. +

+ {props.defaultIndexPattern && props.defaultIndexPattern.isTimeBased() ? ( + <> + + + { + // eslint-disable-next-line no-bitwise + const newColor = '#' + ((Math.random() * 0xffffff) << 0).toString(16); + setColor(newColor); + }} + > + Change color + + + + { + props.plugins.lens.navigateToPrefilledEditor({ + id: '', + timeRange: { + from: 'now-5d', + to: 'now', + }, + attributes: getLensAttributes(props.defaultIndexPattern!, color), + }); + // eslint-disable-next-line no-bitwise + const newColor = '#' + ((Math.random() * 0xffffff) << 0).toString(16); + setColor(newColor); + }} + > + Edit + + + + + + ) : ( +

This demo only works if your default index pattern is set and time based

+ )} +
+
+
+
+ ); +}; diff --git a/x-pack/examples/embedded_lens_example/public/index.ts b/x-pack/examples/embedded_lens_example/public/index.ts new file mode 100644 index 0000000000000..b9a263d5e6e88 --- /dev/null +++ b/x-pack/examples/embedded_lens_example/public/index.ts @@ -0,0 +1,9 @@ +/* + * 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 { EmbeddedLensExamplePlugin } from './plugin'; + +export const plugin = () => new EmbeddedLensExamplePlugin(); diff --git a/x-pack/examples/embedded_lens_example/public/mount.tsx b/x-pack/examples/embedded_lens_example/public/mount.tsx new file mode 100644 index 0000000000000..21d0a01df1636 --- /dev/null +++ b/x-pack/examples/embedded_lens_example/public/mount.tsx @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as React from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; +import { CoreSetup, AppMountParameters } from 'kibana/public'; +import { StartDependencies } from './plugin'; + +export const mount = (coreSetup: CoreSetup) => async ({ + element, +}: AppMountParameters) => { + const [core, plugins] = await coreSetup.getStartServices(); + const { App } = await import('./app'); + + const deps = { + core, + plugins, + }; + + const defaultIndexPattern = await plugins.data.indexPatterns.getDefault(); + + const reactElement = ; + render(reactElement, element); + return () => unmountComponentAtNode(element); +}; diff --git a/x-pack/examples/embedded_lens_example/public/plugin.ts b/x-pack/examples/embedded_lens_example/public/plugin.ts new file mode 100644 index 0000000000000..2f2e988d42025 --- /dev/null +++ b/x-pack/examples/embedded_lens_example/public/plugin.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 { Plugin, CoreSetup, AppNavLinkStatus } from '../../../../src/core/public'; +import { DataPublicPluginStart } from '../../../../src/plugins/data/public'; +import { LensPublicStart } from '../../../plugins/lens/public'; +import { DeveloperExamplesSetup } from '../../../../examples/developer_examples/public'; +import { mount } from './mount'; + +export interface SetupDependencies { + developerExamples: DeveloperExamplesSetup; +} + +export interface StartDependencies { + data: DataPublicPluginStart; + lens: LensPublicStart; +} + +export class EmbeddedLensExamplePlugin + implements Plugin { + public setup(core: CoreSetup, { developerExamples }: SetupDependencies) { + core.application.register({ + id: 'embedded_lens_example', + title: 'Embedded Lens example', + navLinkStatus: AppNavLinkStatus.hidden, + mount: mount(core), + }); + + developerExamples.register({ + appId: 'embedded_lens_example', + title: 'Embedded Lens', + description: + 'Embed Lens visualizations into other applications and link to a pre-configured Lens editor to allow users to use visualizations in your app as starting points for further explorations.', + links: [ + { + label: 'README', + href: + 'https://github.com/elastic/kibana/tree/master/x-pack/examples/embedded_lens_example', + iconType: 'logoGithub', + size: 's', + target: '_blank', + }, + ], + }); + } + + public start() {} + + public stop() {} +} diff --git a/x-pack/examples/embedded_lens_example/tsconfig.json b/x-pack/examples/embedded_lens_example/tsconfig.json new file mode 100644 index 0000000000000..2bf577e87041c --- /dev/null +++ b/x-pack/examples/embedded_lens_example/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./target", + "skipLibCheck": true + }, + "include": [ + "index.ts", + "public/**/*.ts", + "public/**/*.tsx", + "server/**/*.ts", + "../../typings/**/*" + ], + "exclude": [], + "references": [ + { "path": "../../../src/core/tsconfig.json" }, + { "path": "../../../src/plugins/kibana_utils/tsconfig.json" }, + { "path": "../../../src/plugins/kibana_react/tsconfig.json" }, + { "path": "../../../src/plugins/share/tsconfig.json" }, + { "path": "../../../src/plugins/data/tsconfig.json" } + ] +} diff --git a/x-pack/plugins/lens/public/app_plugin/types.ts b/x-pack/plugins/lens/public/app_plugin/types.ts index af0feabe68cf7..46da17a944419 100644 --- a/x-pack/plugins/lens/public/app_plugin/types.ts +++ b/x-pack/plugins/lens/public/app_plugin/types.ts @@ -38,7 +38,7 @@ import { EmbeddableStateTransfer, } from '../../../../../src/plugins/embeddable/public'; import { TableInspectorAdapter } from '../editor_frame_service/types'; -import { EditorFrameInstance } from '..'; +import { EditorFrameInstance } from '../types'; export interface LensAppState { isLoading: boolean; diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx index 175c573d3be3a..04f747f42ac66 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx @@ -214,8 +214,6 @@ describe('embeddable', () => { searchSessionId: 'searchSessionId', }); - expect(expressionRenderer).toHaveBeenCalledTimes(1); - await new Promise((resolve) => setTimeout(resolve, 0)); expect(expressionRenderer).toHaveBeenCalledTimes(2); diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx index ea7ce99e92cef..e2d637dd6684a 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx @@ -57,6 +57,10 @@ interface LensBaseEmbeddableInput extends EmbeddableInput { filters?: Filter[]; query?: Query; timeRange?: TimeRange; + palette?: PaletteOutput; + renderMode?: RenderMode; + style?: React.CSSProperties; + className?: string; } export type LensByValueInput = { @@ -64,10 +68,7 @@ export type LensByValueInput = { } & LensBaseEmbeddableInput; export type LensByReferenceInput = SavedObjectEmbeddableInput & LensBaseEmbeddableInput; -export type LensEmbeddableInput = (LensByValueInput | LensByReferenceInput) & { - palette?: PaletteOutput; - renderMode?: RenderMode; -}; +export type LensEmbeddableInput = LensByValueInput | LensByReferenceInput; export interface LensEmbeddableOutput extends EmbeddableOutput { indexPatterns?: IIndexPattern[]; @@ -159,6 +160,37 @@ export class Embeddable .subscribe((input) => { this.reload(); }); + + // Re-initialize the visualization if either the attributes or the saved object id changes + input$ + .pipe( + distinctUntilChanged((a, b) => + isEqual( + ['attributes' in a && a.attributes, 'savedObjectId' in a && a.savedObjectId], + ['attributes' in b && b.attributes, 'savedObjectId' in b && b.savedObjectId] + ) + ), + skip(1) + ) + .subscribe(async (input) => { + await this.initializeSavedVis(input); + this.reload(); + }); + + // Update search context and reload on changes related to search + input$ + .pipe( + distinctUntilChanged((a, b) => + isEqual( + [a.filters, a.query, a.timeRange, a.searchSessionId], + [b.filters, b.query, b.timeRange, b.searchSessionId] + ) + ), + skip(1) + ) + .subscribe(async (input) => { + this.onContainerStateChanged(input); + }); } public supportedTriggers() { @@ -262,6 +294,8 @@ export class Embeddable renderMode={input.renderMode} syncColors={input.syncColors} hasCompatibleActions={this.hasCompatibleActions} + className={input.className} + style={input.style} />, domNode ); diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable_component.tsx b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable_component.tsx new file mode 100644 index 0000000000000..0a9e9799bbc3a --- /dev/null +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable_component.tsx @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React from 'react'; +import { + EmbeddableRenderer, + EmbeddableStart, +} from '../../../../../../src/plugins/embeddable/public'; +import type { LensByReferenceInput, LensByValueInput } from './embeddable'; +import type { Document } from '../../persistence'; +import type { IndexPatternPersistedState } from '../../indexpattern_datasource/types'; +import type { XYState } from '../../xy_visualization/types'; +import type { PieVisualizationState } from '../../pie_visualization/types'; +import type { DatatableVisualizationState } from '../../datatable_visualization/visualization'; +import type { State as MetricState } from '../../metric_visualization/types'; + +type LensAttributes = Omit< + Document, + 'savedObjectId' | 'type' | 'state' | 'visualizationType' +> & { + visualizationType: TVisType; + state: Omit & { + datasourceStates: { + indexpattern: IndexPatternPersistedState; + }; + visualization: TVisState; + }; +}; + +/** + * Type-safe variant of by value embeddable input for Lens. + * This can be used to hardcode certain Lens chart configurations within another app. + */ +export type TypedLensByValueInput = Omit & { + attributes: + | LensAttributes<'lnsXY', XYState> + | LensAttributes<'lnsPie', PieVisualizationState> + | LensAttributes<'lnsDatatable', DatatableVisualizationState> + | LensAttributes<'lnsMetric', MetricState>; +}; + +export type EmbeddableComponentProps = TypedLensByValueInput | LensByReferenceInput; + +export function getEmbeddableComponent(embeddableStart: EmbeddableStart) { + return (props: EmbeddableComponentProps) => { + const factory = embeddableStart.getEmbeddableFactory('lens')!; + return ; + }; +} diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/expression_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/embeddable/expression_wrapper.tsx index c91ca74b54a4f..31f4690d8b7b7 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/expression_wrapper.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/expression_wrapper.tsx @@ -15,6 +15,7 @@ import { } from 'src/plugins/expressions/public'; import { ExecutionContextSearch } from 'src/plugins/data/public'; import { DefaultInspectorAdapters, RenderMode } from 'src/plugins/expressions'; +import classNames from 'classnames'; import { getOriginalRequestErrorMessage } from '../error_helper'; export interface ExpressionWrapperProps { @@ -31,6 +32,8 @@ export interface ExpressionWrapperProps { renderMode?: RenderMode; syncColors?: boolean; hasCompatibleActions?: ReactExpressionRendererProps['hasCompatibleActions']; + style?: React.CSSProperties; + className?: string; } export function ExpressionWrapper({ @@ -44,6 +47,8 @@ export function ExpressionWrapper({ renderMode, syncColors, hasCompatibleActions, + style, + className, }: ExpressionWrapperProps) { return ( @@ -62,7 +67,7 @@ export function ExpressionWrapper({ ) : ( -
+
new LensPlugin(); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx index 6c6bd2e1bb439..48592c44aa543 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx @@ -47,7 +47,7 @@ import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/p import { DataPublicPluginStart } from '../../../../../src/plugins/data/public'; import { VisualizeFieldContext } from '../../../../../src/plugins/ui_actions/public'; import { mergeLayer } from './state_helpers'; -import { Datasource, StateSetter } from '../index'; +import { Datasource, StateSetter } from '../types'; import { ChartsPluginSetup } from '../../../../../src/plugins/charts/public'; import { deleteColumn, isReferenced } from './operations'; import { Dragging } from '../drag_drop/providers'; diff --git a/x-pack/plugins/lens/public/metric_visualization/metric_suggestions.test.ts b/x-pack/plugins/lens/public/metric_visualization/metric_suggestions.test.ts index 2a659e5fe10c4..681905afe52da 100644 --- a/x-pack/plugins/lens/public/metric_visualization/metric_suggestions.test.ts +++ b/x-pack/plugins/lens/public/metric_visualization/metric_suggestions.test.ts @@ -5,7 +5,7 @@ */ import { getSuggestions } from './metric_suggestions'; -import { TableSuggestionColumn, TableSuggestion } from '../index'; +import { TableSuggestionColumn, TableSuggestion } from '../types'; describe('metric_suggestions', () => { function numCol(columnId: string): TableSuggestionColumn { diff --git a/x-pack/plugins/lens/public/plugin.ts b/x-pack/plugins/lens/public/plugin.ts index 24075facb68eb..cdffdb342fd23 100644 --- a/x-pack/plugins/lens/public/plugin.ts +++ b/x-pack/plugins/lens/public/plugin.ts @@ -17,6 +17,7 @@ import { NavigationPublicPluginStart } from '../../../../src/plugins/navigation/ import { UrlForwardingSetup } from '../../../../src/plugins/url_forwarding/public'; import { GlobalSearchPluginSetup } from '../../global_search/public'; import { ChartsPluginSetup, ChartsPluginStart } from '../../../../src/plugins/charts/public'; +import { EmbeddableStateTransfer } from '../../../../src/plugins/embeddable/public'; import { EditorFrameService } from './editor_frame_service'; import { IndexPatternDatasource, @@ -37,7 +38,7 @@ import { ACTION_VISUALIZE_FIELD, VISUALIZE_FIELD_TRIGGER, } from '../../../../src/plugins/ui_actions/public'; -import { NOT_INTERNATIONALIZED_PRODUCT_NAME } from '../common'; +import { getEditPath, NOT_INTERNATIONALIZED_PRODUCT_NAME } from '../common'; import { PLUGIN_ID_OSS } from '../../../../src/plugins/lens_oss/common/constants'; import { EditorFrameStart } from './types'; import { getLensAliasConfig } from './vis_type_alias'; @@ -45,6 +46,11 @@ import { visualizeFieldAction } from './trigger_actions/visualize_field_actions' import { getSearchProvider } from './search_provider'; import { LensAttributeService } from './lens_attribute_service'; +import { LensEmbeddableInput } from './editor_frame_service/embeddable'; +import { + EmbeddableComponentProps, + getEmbeddableComponent, +} from './editor_frame_service/embeddable/embeddable_component'; export interface LensPluginSetupDependencies { urlForwarding: UrlForwardingSetup; @@ -68,6 +74,31 @@ export interface LensPluginStartDependencies { savedObjectsTagging?: SavedObjectTaggingPluginStart; } +export interface LensPublicStart { + /** + * React component which can be used to embed a Lens visualization into another application. + * See `x-pack/examples/embedded_lens_example` for exemplary usage. + * + * This API might undergo breaking changes even in minor versions. + * + * @experimental + */ + EmbeddableComponent: React.ComponentType; + /** + * Method which navigates to the Lens editor, loading the state specified by the `input` parameter. + * See `x-pack/examples/embedded_lens_example` for exemplary usage. + * + * This API might undergo breaking changes even in minor versions. + * + * @experimental + */ + navigateToPrefilledEditor: (input: LensEmbeddableInput) => void; + /** + * Method which returns true if the user has permission to use Lens as defined by application capabilities. + */ + canUseEditor: () => boolean; +} + export class LensPlugin { private datatableVisualization: DatatableVisualization; private editorFrameService: EditorFrameService; @@ -174,8 +205,9 @@ export class LensPlugin { urlForwarding.forwardApp('lens', 'lens'); } - start(core: CoreStart, startDependencies: LensPluginStartDependencies) { - this.createEditorFrame = this.editorFrameService.start(core, startDependencies).createInstance; + start(core: CoreStart, startDependencies: LensPluginStartDependencies): LensPublicStart { + const frameStart = this.editorFrameService.start(core, startDependencies); + this.createEditorFrame = frameStart.createInstance; // unregisters the OSS alias startDependencies.visualizations.unRegisterAlias(PLUGIN_ID_OSS); // unregisters the Visualize action and registers the lens one @@ -186,6 +218,29 @@ export class LensPlugin { VISUALIZE_FIELD_TRIGGER, visualizeFieldAction(core.application) ); + + return { + EmbeddableComponent: getEmbeddableComponent(startDependencies.embeddable), + navigateToPrefilledEditor: (input: LensEmbeddableInput) => { + if (input.timeRange) { + startDependencies.data.query.timefilter.timefilter.setTime(input.timeRange); + } + const transfer = new EmbeddableStateTransfer( + core.application.navigateToApp, + core.application.currentAppId$ + ); + transfer.navigateToEditor('lens', { + path: getEditPath(undefined), + state: { + originatingApp: '', + valueInput: input, + }, + }); + }, + canUseEditor: () => { + return Boolean(core.application.capabilities.visualize?.show); + }, + }; } stop() { diff --git a/x-pack/plugins/lens/public/xy_visualization/types.ts b/x-pack/plugins/lens/public/xy_visualization/types.ts index d21ac675d0745..88e95f2ca3271 100644 --- a/x-pack/plugins/lens/public/xy_visualization/types.ts +++ b/x-pack/plugins/lens/public/xy_visualization/types.ts @@ -19,7 +19,7 @@ import { LensIconChartBarHorizontalStacked } from '../assets/chart_bar_horizonta import { LensIconChartBarHorizontalPercentage } from '../assets/chart_bar_horizontal_percentage'; import { LensIconChartLine } from '../assets/chart_line'; -import { VisualizationType } from '../index'; +import { VisualizationType } from '../types'; import { FittingFunction } from './fitting_functions'; export interface LegendConfig { From 5598df9f7d5c9ff5121bd6876b42448e615bf023 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Jan 2021 12:07:16 +0200 Subject: [PATCH 30/64] Update dependency vega to ^5.18.0 (#87921) Co-authored-by: Renovate Bot Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 8af20d6459373..f8fe8d7c7bac4 100644 --- a/package.json +++ b/package.json @@ -829,7 +829,7 @@ "url-loader": "^2.2.0", "use-resize-observer": "^6.0.0", "val-loader": "^1.1.1", - "vega": "^5.17.3", + "vega": "^5.18.0", "vega-lite": "^4.17.0", "vega-schema-url-parser": "^2.1.0", "vega-tooltip": "^0.25.0", diff --git a/yarn.lock b/yarn.lock index e101dff70761c..9c27686f1e922 100644 --- a/yarn.lock +++ b/yarn.lock @@ -28521,7 +28521,7 @@ vega-format@^1.0.4, vega-format@~1.0.4: vega-time "^2.0.3" vega-util "^1.15.2" -vega-functions@^5.10.0, vega-functions@~5.10.0: +vega-functions@^5.10.0: version "5.10.0" resolved "https://registry.yarnpkg.com/vega-functions/-/vega-functions-5.10.0.tgz#3d384111f13b3b0dd38a4fca656c5ae54b66e158" integrity sha512-1l28OxUwOj8FEvRU62Oz2hiTuDECrvx1DPU1qLebBKhlgaKbcCk3XyHrn1kUzhMKpXq+SFv5VPxchZP47ASSvQ== @@ -28538,6 +28538,23 @@ vega-functions@^5.10.0, vega-functions@~5.10.0: vega-time "^2.0.4" vega-util "^1.16.0" +vega-functions@~5.11.0: + version "5.11.0" + resolved "https://registry.yarnpkg.com/vega-functions/-/vega-functions-5.11.0.tgz#a590d016f93c81730bdbc336b377231d7ae48569" + integrity sha512-/p0QIDiA3RaUZ7drxHuClpDQCrIScSHJlY0oo0+GFYGfp+lvb29Ox1T4a+wtqeCp6NRaTWry+EwDxojnshTZIQ== + dependencies: + d3-array "^2.7.1" + d3-color "^2.0.0" + d3-geo "^2.0.1" + vega-dataflow "^5.7.3" + vega-expression "^4.0.1" + vega-scale "^7.1.1" + vega-scenegraph "^4.9.2" + vega-selections "^5.2.0" + vega-statistics "^1.7.9" + vega-time "^2.0.4" + vega-util "^1.16.0" + vega-geo@~4.3.8: version "4.3.8" resolved "https://registry.yarnpkg.com/vega-geo/-/vega-geo-4.3.8.tgz#5629d18327bb4f3700cdf05db4aced0a43abbf4a" @@ -28673,6 +28690,14 @@ vega-selections@^5.1.5: vega-expression "^4.0.0" vega-util "^1.15.2" +vega-selections@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/vega-selections/-/vega-selections-5.2.0.tgz#d85968d1bccc175fd92661c91d88151ffd5ade83" + integrity sha512-Xf3nTTJHRGw4tQMbt+0sBI/7WkEIzPG9E4HXkZk5Y9Q2HsGRVLmrAEXHSfpENrBLWTBZk/uvmP9rKDG7cbcTrg== + dependencies: + vega-expression "^4.0.1" + vega-util "^1.16.0" + vega-spec-injector@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/vega-spec-injector/-/vega-spec-injector-0.0.2.tgz#f1d990109dd9d845c524738f818baa4b72a60ca6" @@ -28767,10 +28792,10 @@ vega-wordcloud@~4.1.3: vega-statistics "^1.7.9" vega-util "^1.15.2" -vega@^5.17.3: - version "5.17.3" - resolved "https://registry.yarnpkg.com/vega/-/vega-5.17.3.tgz#9901f24c8cf5ff2e98f3fddb372b8f5a6d8502d8" - integrity sha512-c8N2pNg9MMmC6shNpoxVw3aVp2XPFOgmWNX5BEOAdCaGHRnSgzNy44+gYdGRaIe6+ljTzZg99Mf+OLO50IP42A== +vega@^5.18.0: + version "5.18.0" + resolved "https://registry.yarnpkg.com/vega/-/vega-5.18.0.tgz#98645e5d3bd5267d66ea3e701d99dcff63cfff8a" + integrity sha512-ysqouhboWNXSuQNN7W5IGOXsnEJNFVX5duCi0tTwRsFLc61FshpqVh4+4VoXg5pH0ZCxwpqbOwd2ULZWjJTx6g== dependencies: vega-crossfilter "~4.0.5" vega-dataflow "~5.7.3" @@ -28779,7 +28804,7 @@ vega@^5.17.3: vega-expression "~4.0.1" vega-force "~4.0.7" vega-format "~1.0.4" - vega-functions "~5.10.0" + vega-functions "~5.11.0" vega-geo "~4.3.8" vega-hierarchy "~4.0.9" vega-label "~1.0.0" From 83e8fe8ef09d81d71db138533657cdca8d8c72f5 Mon Sep 17 00:00:00 2001 From: Dima Arnautov Date: Tue, 12 Jan 2021 13:03:47 +0100 Subject: [PATCH 31/64] [Transform] Show destination index mapping warning for the latest transform (#87858) * [Transform] show callout for the latest transform * [Transform] fix flex styles * [Transform] change to vertical layout, update warning message * [Transform] fix messages --- .../step_define/step_define_summary.tsx | 4 +-- .../step_details/step_details_form.tsx | 28 +++++++++++++++++++ .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.tsx index af2f56fe942de..4d2cb0e71a021 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.tsx +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.tsx @@ -191,8 +191,8 @@ export const StepDefineSummary: FC = ({ } )} dataTestSubj="transformPivotPreview" - title={i18n.translate('xpack.transform.pivotPreview.PivotPreviewTitle', { - defaultMessage: 'Transform pivot preview', + title={i18n.translate('xpack.transform.pivotPreview.transformPreviewTitle', { + defaultMessage: 'Transform preview', })} toastNotifications={toastNotifications} /> diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx index c58d873c9834a..b72d70295b10f 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx @@ -7,6 +7,7 @@ import React, { Fragment, FC, useEffect, useState } from 'react'; import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; import { EuiAccordion, @@ -17,6 +18,7 @@ import { EuiFormRow, EuiSelect, EuiSpacer, + EuiCallOut, } from '@elastic/eui'; import { KBN_FIELD_TYPES } from '../../../../../../../../../src/plugins/data/common'; @@ -50,6 +52,7 @@ import { transformSettingsMaxPageSearchSizeValidator, } from '../../../../common/validators'; import { StepDefineExposedState } from '../step_define/common'; +import { TRANSFORM_FUNCTION } from '../../../../../../common/constants'; export interface StepDetailsExposedState { continuousModeDateField: string; @@ -397,6 +400,7 @@ export const StepDetailsForm: FC = React.memo( data-test-subj="transformDescriptionInput" /> + = React.memo( /> + {stepDefineState.transformFunction === TRANSFORM_FUNCTION.LATEST ? ( + <> + + +

+ + {i18n.translate('xpack.transform.stepDetailsForm.createIndexAPI', { + defaultMessage: 'Create index API', + })} + + ), + }} + /> +

+
+ + + ) : null} + Date: Tue, 12 Jan 2021 13:51:54 +0100 Subject: [PATCH 32/64] Do not embedd credentials into ES URL and enable anonymous tests. (#87987) --- test/common/config.js | 9 ++++++++- x-pack/scripts/functional_tests.js | 1 + x-pack/test/functional/page_objects/security_page.ts | 11 +++++------ .../security_api_integration/tests/anonymous/login.ts | 6 +++--- .../tests/kerberos/kerberos_login.ts | 6 +++--- .../tests/oidc/authorization_code_flow/oidc_auth.ts | 9 ++++----- .../security_api_integration/tests/pki/pki_auth.ts | 7 +++---- .../security_api_integration/tests/saml/saml_login.ts | 6 +++--- .../tests/session_idle/cleanup.ts | 3 ++- .../tests/session_lifespan/cleanup.ts | 3 ++- 10 files changed, 34 insertions(+), 27 deletions(-) diff --git a/test/common/config.js b/test/common/config.js index 6c7d64e3e0bc0..6809b87bc807d 100644 --- a/test/common/config.js +++ b/test/common/config.js @@ -44,7 +44,14 @@ export default function () { '--logging.json=false', `--server.port=${kbnTestConfig.getPort()}`, '--status.allowAnonymous=true', - `--elasticsearch.hosts=${formatUrl(servers.elasticsearch)}`, + // We shouldn't embed credentials into the URL since Kibana requests to Elasticsearch should + // either include `kibanaServerTestUser` credentials, or credentials provided by the test + // user, or none at all in case anonymous access is used. + `--elasticsearch.hosts=${formatUrl( + Object.fromEntries( + Object.entries(servers.elasticsearch).filter(([key]) => key.toLowerCase() !== 'auth') + ) + )}`, `--elasticsearch.username=${kibanaServerTestUser.username}`, `--elasticsearch.password=${kibanaServerTestUser.password}`, `--home.disableWelcomeScreen=true`, diff --git a/x-pack/scripts/functional_tests.js b/x-pack/scripts/functional_tests.js index 4067d70384eab..eff3a24a0ff3a 100644 --- a/x-pack/scripts/functional_tests.js +++ b/x-pack/scripts/functional_tests.js @@ -45,6 +45,7 @@ const onlyNotInCoverageTests = [ require.resolve('../test/security_api_integration/oidc_implicit_flow.config.ts'), require.resolve('../test/security_api_integration/token.config.ts'), require.resolve('../test/security_api_integration/anonymous.config.ts'), + require.resolve('../test/security_api_integration/anonymous_es_anonymous.config.ts'), require.resolve('../test/observability_api_integration/basic/config.ts'), require.resolve('../test/observability_api_integration/trial/config.ts'), require.resolve('../test/encrypted_saved_objects_api_integration/config.ts'), diff --git a/x-pack/test/functional/page_objects/security_page.ts b/x-pack/test/functional/page_objects/security_page.ts index aca37d3d058e7..cad5e29528e9c 100644 --- a/x-pack/test/functional/page_objects/security_page.ts +++ b/x-pack/test/functional/page_objects/security_page.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { adminTestUser } from '@kbn/test'; import { FtrProviderContext } from '../ftr_provider_context'; import { AuthenticatedUser, Role } from '../../../plugins/security/common/model'; @@ -122,9 +123,8 @@ export function SecurityPageProvider({ getService, getPageObjects }: FtrProvider await browser.setLocalStorageItem('home:welcome:show', 'false'); await waitForLoginForm(); - const [superUsername, superPassword] = config.get('servers.elasticsearch.auth').split(':'); - await testSubjects.setValue('loginUsername', username || superUsername); - await testSubjects.setValue('loginPassword', password || superPassword); + await testSubjects.setValue('loginUsername', username || adminTestUser.username); + await testSubjects.setValue('loginPassword', password || adminTestUser.password); await testSubjects.click('loginSubmit'); await waitForLoginResult( @@ -162,9 +162,8 @@ export function SecurityPageProvider({ getService, getPageObjects }: FtrProvider if (providerType === 'basic' || providerType === 'token') { await waitForLoginForm(); - const [superUsername, superPassword] = config.get('servers.elasticsearch.auth').split(':'); - await testSubjects.setValue('loginUsername', options?.username ?? superUsername); - await testSubjects.setValue('loginPassword', options?.password ?? superPassword); + await testSubjects.setValue('loginUsername', options?.username ?? adminTestUser.username); + await testSubjects.setValue('loginPassword', options?.password ?? adminTestUser.password); await testSubjects.click('loginSubmit'); } diff --git a/x-pack/test/security_api_integration/tests/anonymous/login.ts b/x-pack/test/security_api_integration/tests/anonymous/login.ts index eaf999c509741..7698c61d64ae7 100644 --- a/x-pack/test/security_api_integration/tests/anonymous/login.ts +++ b/x-pack/test/security_api_integration/tests/anonymous/login.ts @@ -6,6 +6,7 @@ import expect from '@kbn/expect'; import request, { Cookie } from 'request'; +import { adminTestUser } from '@kbn/test'; import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { @@ -55,7 +56,6 @@ export default function ({ getService }: FtrProviderContext) { }); it('does not prevent basic login', async () => { - const [username, password] = config.get('servers.elasticsearch.auth').split(':'); const response = await supertest .post('/internal/security/login') .set('kbn-xsrf', 'xxx') @@ -63,7 +63,7 @@ export default function ({ getService }: FtrProviderContext) { providerType: 'basic', providerName: 'basic1', currentURL: '/', - params: { username, password }, + params: { username: adminTestUser.username, password: adminTestUser.password }, }) .expect(200); @@ -79,7 +79,7 @@ export default function ({ getService }: FtrProviderContext) { .set('Cookie', cookie.cookieString()) .expect(200); - expect(user.username).to.eql(username); + expect(user.username).to.eql(adminTestUser.username); expect(user.authentication_provider).to.eql({ type: 'basic', name: 'basic1' }); expect(user.authentication_type).to.eql('realm'); // Do not assert on the `authentication_realm`, as the value differs for on-prem vs cloud diff --git a/x-pack/test/security_api_integration/tests/kerberos/kerberos_login.ts b/x-pack/test/security_api_integration/tests/kerberos/kerberos_login.ts index 7e2e6647d7234..4a21cbd4b3943 100644 --- a/x-pack/test/security_api_integration/tests/kerberos/kerberos_login.ts +++ b/x-pack/test/security_api_integration/tests/kerberos/kerberos_login.ts @@ -7,6 +7,7 @@ import expect from '@kbn/expect'; import request, { Cookie } from 'request'; import { delay } from 'bluebird'; +import { adminTestUser } from '@kbn/test'; import { FtrProviderContext } from '../../ftr_provider_context'; import { getMutualAuthenticationResponseToken, @@ -54,7 +55,6 @@ export default function ({ getService }: FtrProviderContext) { }); it('does not prevent basic login', async () => { - const [username, password] = config.get('servers.elasticsearch.auth').split(':'); const response = await supertest .post('/internal/security/login') .set('kbn-xsrf', 'xxx') @@ -62,7 +62,7 @@ export default function ({ getService }: FtrProviderContext) { providerType: 'basic', providerName: 'basic', currentURL: '/', - params: { username, password }, + params: { username: adminTestUser.username, password: adminTestUser.password }, }) .expect(200); @@ -78,7 +78,7 @@ export default function ({ getService }: FtrProviderContext) { .set('Cookie', cookie.cookieString()) .expect(200); - expect(user.username).to.eql(username); + expect(user.username).to.eql(adminTestUser.username); expect(user.authentication_provider).to.eql({ type: 'basic', name: 'basic' }); expect(user.authentication_type).to.eql('realm'); // Do not assert on the `authentication_realm`, as the value differs for on-prem vs cloud diff --git a/x-pack/test/security_api_integration/tests/oidc/authorization_code_flow/oidc_auth.ts b/x-pack/test/security_api_integration/tests/oidc/authorization_code_flow/oidc_auth.ts index ff7c211d38de2..efc307399d3f2 100644 --- a/x-pack/test/security_api_integration/tests/oidc/authorization_code_flow/oidc_auth.ts +++ b/x-pack/test/security_api_integration/tests/oidc/authorization_code_flow/oidc_auth.ts @@ -8,12 +8,12 @@ import expect from '@kbn/expect'; import request, { Cookie } from 'request'; import url from 'url'; import { delay } from 'bluebird'; +import { adminTestUser } from '@kbn/test'; import { getStateAndNonce } from '../../../fixtures/oidc/oidc_tools'; import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertestWithoutAuth'); - const config = getService('config'); describe('OpenID Connect authentication', () => { it('should reject API requests if client is not authenticated', async () => { @@ -21,7 +21,6 @@ export default function ({ getService }: FtrProviderContext) { }); it('does not prevent basic login', async () => { - const [username, password] = config.get('servers.elasticsearch.auth').split(':'); const response = await supertest .post('/internal/security/login') .set('kbn-xsrf', 'xxx') @@ -29,7 +28,7 @@ export default function ({ getService }: FtrProviderContext) { providerType: 'basic', providerName: 'basic', currentURL: '/', - params: { username, password }, + params: { username: adminTestUser.username, password: adminTestUser.password }, }) .expect(200); @@ -42,10 +41,10 @@ export default function ({ getService }: FtrProviderContext) { .set('Cookie', request.cookie(cookies[0])!.cookieString()) .expect(200); - expect(user.username).to.eql(username); + expect(user.username).to.eql(adminTestUser.username); expect(user.authentication_provider).to.eql({ type: 'basic', name: 'basic' }); expect(user.authentication_type).to.be('realm'); - // Do not assert on the `authentication_realm`, as the value differes for on-prem vs cloud + // Do not assert on the `authentication_realm`, as the value differs for on-prem vs cloud }); describe('initiating handshake', () => { diff --git a/x-pack/test/security_api_integration/tests/pki/pki_auth.ts b/x-pack/test/security_api_integration/tests/pki/pki_auth.ts index 0d630dab51cf7..4954bcddc2396 100644 --- a/x-pack/test/security_api_integration/tests/pki/pki_auth.ts +++ b/x-pack/test/security_api_integration/tests/pki/pki_auth.ts @@ -10,6 +10,7 @@ import { delay } from 'bluebird'; import { readFileSync } from 'fs'; import { resolve } from 'path'; import { CA_CERT_PATH } from '@kbn/dev-utils'; +import { adminTestUser } from '@kbn/test'; import { FtrProviderContext } from '../../ftr_provider_context'; const CA_CERT = readFileSync(CA_CERT_PATH); @@ -21,7 +22,6 @@ const UNTRUSTED_CLIENT_CERT = readFileSync( export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertestWithoutAuth'); - const config = getService('config'); function checkCookieIsSet(cookie: Cookie) { expect(cookie.value).to.not.be.empty(); @@ -64,7 +64,6 @@ export default function ({ getService }: FtrProviderContext) { }); it('does not prevent basic login', async () => { - const [username, password] = config.get('servers.elasticsearch.auth').split(':'); const response = await supertest .post('/internal/security/login') .ca(CA_CERT) @@ -74,7 +73,7 @@ export default function ({ getService }: FtrProviderContext) { providerType: 'basic', providerName: 'basic', currentURL: '/', - params: { username, password }, + params: { username: adminTestUser.username, password: adminTestUser.password }, }) .expect(200); @@ -92,7 +91,7 @@ export default function ({ getService }: FtrProviderContext) { .set('Cookie', cookie.cookieString()) .expect(200); - expect(user.username).to.eql(username); + expect(user.username).to.eql(adminTestUser.username); expect(user.authentication_provider).to.eql({ type: 'basic', name: 'basic' }); // Do not assert on the `authentication_realm`, as the value differs for on-prem vs cloud }); diff --git a/x-pack/test/security_api_integration/tests/saml/saml_login.ts b/x-pack/test/security_api_integration/tests/saml/saml_login.ts index c76b39a1ea772..d76da2023ddda 100644 --- a/x-pack/test/security_api_integration/tests/saml/saml_login.ts +++ b/x-pack/test/security_api_integration/tests/saml/saml_login.ts @@ -9,6 +9,7 @@ import url from 'url'; import { delay } from 'bluebird'; import expect from '@kbn/expect'; import request, { Cookie } from 'request'; +import { adminTestUser } from '@kbn/test'; import { getLogoutRequest, getSAMLRequestId, @@ -75,7 +76,6 @@ export default function ({ getService }: FtrProviderContext) { }); it('does not prevent basic login', async () => { - const [username, password] = config.get('servers.elasticsearch.auth').split(':'); const response = await supertest .post('/internal/security/login') .set('kbn-xsrf', 'xxx') @@ -83,7 +83,7 @@ export default function ({ getService }: FtrProviderContext) { providerType: 'basic', providerName: 'basic', currentURL: '/', - params: { username, password }, + params: { username: adminTestUser.username, password: adminTestUser.password }, }) .expect(200); @@ -96,7 +96,7 @@ export default function ({ getService }: FtrProviderContext) { .set('Cookie', request.cookie(cookies[0])!.cookieString()) .expect(200); - expect(user.username).to.eql(username); + expect(user.username).to.eql(adminTestUser.username); expect(user.authentication_provider).to.eql({ type: 'basic', name: 'basic' }); expect(user.authentication_type).to.be('realm'); // Do not assert on the `authentication_realm`, as the value differes for on-prem vs cloud diff --git a/x-pack/test/security_api_integration/tests/session_idle/cleanup.ts b/x-pack/test/security_api_integration/tests/session_idle/cleanup.ts index a5fc0a2134fc0..bd9b66b48be50 100644 --- a/x-pack/test/security_api_integration/tests/session_idle/cleanup.ts +++ b/x-pack/test/security_api_integration/tests/session_idle/cleanup.ts @@ -7,6 +7,7 @@ import request, { Cookie } from 'request'; import { delay } from 'bluebird'; import expect from '@kbn/expect'; +import { adminTestUser } from '@kbn/test'; import type { AuthenticationProvider } from '../../../../plugins/security/common/model'; import { getSAMLRequestId, getSAMLResponse } from '../../fixtures/saml/saml_tools'; import { FtrProviderContext } from '../../ftr_provider_context'; @@ -17,7 +18,7 @@ export default function ({ getService }: FtrProviderContext) { const config = getService('config'); const log = getService('log'); const randomness = getService('randomness'); - const [basicUsername, basicPassword] = config.get('servers.elasticsearch.auth').split(':'); + const { username: basicUsername, password: basicPassword } = adminTestUser; const kibanaServerConfig = config.get('servers.kibana'); async function checkSessionCookie( diff --git a/x-pack/test/security_api_integration/tests/session_lifespan/cleanup.ts b/x-pack/test/security_api_integration/tests/session_lifespan/cleanup.ts index 100fa3f21fe01..7abab0c0b2e15 100644 --- a/x-pack/test/security_api_integration/tests/session_lifespan/cleanup.ts +++ b/x-pack/test/security_api_integration/tests/session_lifespan/cleanup.ts @@ -7,6 +7,7 @@ import request, { Cookie } from 'request'; import { delay } from 'bluebird'; import expect from '@kbn/expect'; +import { adminTestUser } from '@kbn/test'; import type { AuthenticationProvider } from '../../../../plugins/security/common/model'; import { getSAMLRequestId, getSAMLResponse } from '../../fixtures/saml/saml_tools'; import { FtrProviderContext } from '../../ftr_provider_context'; @@ -16,7 +17,7 @@ export default function ({ getService }: FtrProviderContext) { const es = getService('es'); const config = getService('config'); const randomness = getService('randomness'); - const [basicUsername, basicPassword] = config.get('servers.elasticsearch.auth').split(':'); + const { username: basicUsername, password: basicPassword } = adminTestUser; const kibanaServerConfig = config.get('servers.kibana'); async function checkSessionCookie( From 02695ef5adbc3ec68abfd02a403d840c37927bca Mon Sep 17 00:00:00 2001 From: Paul Tavares <56442535+paul-tavares@users.noreply.github.com> Date: Tue, 12 Jan 2021 07:56:05 -0500 Subject: [PATCH 33/64] [Fleet] Show Count of Agent Policies on Integration Details (#86916) * component to show count of agent policies for integration * API route and service to return stats of package usage --- .../plugins/fleet/common/constants/routes.ts | 1 + .../plugins/fleet/common/services/routes.ts | 4 + .../plugins/fleet/common/types/models/epm.ts | 4 + .../fleet/common/types/rest_spec/epm.ts | 11 ++ .../fleet/hooks/use_request/epm.ts | 8 + .../epm/screens/detail/index.test.tsx | 108 +++++++++-- .../sections/epm/screens/detail/index.tsx | 16 +- .../detail/integration_agent_policy_count.tsx | 17 ++ .../fleet/server/routes/epm/handlers.ts | 20 ++ .../plugins/fleet/server/routes/epm/index.ts | 11 ++ .../server/services/epm/packages/get.test.ts | 171 ++++++++++++++++++ .../fleet/server/services/epm/packages/get.ts | 46 ++++- .../fleet/server/types/rest_spec/epm.ts | 6 + 13 files changed, 402 insertions(+), 21 deletions(-) create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/epm/screens/detail/integration_agent_policy_count.tsx create mode 100644 x-pack/plugins/fleet/server/services/epm/packages/get.test.ts diff --git a/x-pack/plugins/fleet/common/constants/routes.ts b/x-pack/plugins/fleet/common/constants/routes.ts index ed38d8a29f035..a583f38419ae1 100644 --- a/x-pack/plugins/fleet/common/constants/routes.ts +++ b/x-pack/plugins/fleet/common/constants/routes.ts @@ -29,6 +29,7 @@ export const EPM_API_ROUTES = { DELETE_PATTERN: EPM_PACKAGES_ONE, FILEPATH_PATTERN: `${EPM_PACKAGES_FILE}/{filePath*}`, CATEGORIES_PATTERN: `${EPM_API_ROOT}/categories`, + STATS_PATTERN: `${EPM_PACKAGES_MANY}/{pkgName}/stats`, }; // Data stream API routes diff --git a/x-pack/plugins/fleet/common/services/routes.ts b/x-pack/plugins/fleet/common/services/routes.ts index 4af3f3beb32be..89c8a7ef40729 100644 --- a/x-pack/plugins/fleet/common/services/routes.ts +++ b/x-pack/plugins/fleet/common/services/routes.ts @@ -35,6 +35,10 @@ export const epmRouteService = { return EPM_API_ROUTES.INFO_PATTERN.replace('{pkgkey}', pkgkey); }, + getStatsPath: (pkgName: string) => { + return EPM_API_ROUTES.STATS_PATTERN.replace('{pkgName}', pkgName); + }, + getFilePath: (filePath: string) => { return `${EPM_API_ROOT}${filePath.replace('/package', '/packages')}`; }, diff --git a/x-pack/plugins/fleet/common/types/models/epm.ts b/x-pack/plugins/fleet/common/types/models/epm.ts index 77625e48dbc96..08f92f406b90f 100644 --- a/x-pack/plugins/fleet/common/types/models/epm.ts +++ b/x-pack/plugins/fleet/common/types/models/epm.ts @@ -279,6 +279,10 @@ export interface Installation extends SavedObjectAttributes { install_source: InstallSource; } +export interface PackageUsageStats { + agent_policy_count: number; +} + export type Installable = Installed | NotInstalled; export type Installed = T & { diff --git a/x-pack/plugins/fleet/common/types/rest_spec/epm.ts b/x-pack/plugins/fleet/common/types/rest_spec/epm.ts index 7299fbb5e5d65..f931138f7ad49 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/epm.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/epm.ts @@ -10,6 +10,7 @@ import { Installable, RegistrySearchResult, PackageInfo, + PackageUsageStats, } from '../models/epm'; export interface GetCategoriesRequest { @@ -54,6 +55,16 @@ export interface GetInfoResponse { response: PackageInfo; } +export interface GetStatsRequest { + params: { + pkgname: string; + }; +} + +export interface GetStatsResponse { + response: PackageUsageStats; +} + export interface InstallPackageRequest { params: { pkgkey: string; diff --git a/x-pack/plugins/fleet/public/applications/fleet/hooks/use_request/epm.ts b/x-pack/plugins/fleet/public/applications/fleet/hooks/use_request/epm.ts index 40a22f6b44d50..d8bf7d208c05f 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/hooks/use_request/epm.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/hooks/use_request/epm.ts @@ -16,6 +16,7 @@ import { InstallPackageResponse, DeletePackageResponse, } from '../../types'; +import { GetStatsResponse } from '../../../../../common'; export const useGetCategories = (query: GetCategoriesRequest['query'] = {}) => { return useRequest({ @@ -47,6 +48,13 @@ export const useGetPackageInfoByKey = (pkgkey: string) => { }); }; +export const useGetPackageStats = (pkgName: string) => { + return useRequest({ + path: epmRouteService.getStatsPath(pkgName), + method: 'get', + }); +}; + export const sendGetPackageInfoByKey = (pkgkey: string) => { return sendRequest({ path: epmRouteService.getInfoPath(pkgkey), diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/epm/screens/detail/index.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/epm/screens/detail/index.test.tsx index 2e4c65955e0da..7709e494cf9fc 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/epm/screens/detail/index.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/epm/screens/detail/index.test.tsx @@ -14,6 +14,7 @@ import { GetFleetStatusResponse, GetInfoResponse, GetPackagePoliciesResponse, + GetStatsResponse, } from '../../../../../../../common/types/rest_spec'; import { DetailViewPanelName, KibanaAssetType } from '../../../../../../../common/types/models'; import { @@ -29,7 +30,7 @@ describe('when on integration detail', () => { const detailPageUrlPath = pagePathGetters.integration_details({ pkgkey }); let testRenderer: TestRenderer; let renderResult: ReturnType; - let mockedApi: MockedApi; + let mockedApi: MockedApi; const render = () => (renderResult = testRenderer.render( @@ -48,6 +49,39 @@ describe('when on integration detail', () => { window.location.hash = '#/'; }); + describe('and the package is installed', () => { + beforeEach(() => render()); + + it('should display agent policy usage count', async () => { + await mockedApi.waitForApi(); + expect(renderResult.queryByTestId('agentPolicyCount')).not.toBeNull(); + }); + + it('should show the Policies tab', async () => { + await mockedApi.waitForApi(); + expect(renderResult.queryByTestId('tab-policies')).not.toBeNull(); + }); + }); + + describe('and the package is not installed', () => { + beforeEach(() => { + const unInstalledPackage = mockedApi.responseProvider.epmGetInfo(); + unInstalledPackage.response.status = 'not_installed'; + mockedApi.responseProvider.epmGetInfo.mockReturnValue(unInstalledPackage); + render(); + }); + + it('should NOT display agent policy usage count', async () => { + await mockedApi.waitForApi(); + expect(renderResult.queryByTestId('agentPolicyCount')).toBeNull(); + }); + + it('should NOT the Policies tab', async () => { + await mockedApi.waitForApi(); + expect(renderResult.queryByTestId('tab-policies')).toBeNull(); + }); + }); + describe('and a custom UI extension is NOT registered', () => { beforeEach(() => render()); @@ -190,12 +224,27 @@ describe('when on integration detail', () => { }); }); -interface MockedApi { +interface MockedApi< + R extends Record> = Record> +> { /** Will return a promise that resolves when triggered APIs are complete */ waitForApi: () => Promise; + /** A object containing the list of API response provider functions that are used by the mocked API */ + responseProvider: R; } -const mockApiCalls = (http: MockedFleetStartServices['http']): MockedApi => { +interface EpmPackageDetailsResponseProvidersMock { + epmGetInfo: jest.MockedFunction<() => GetInfoResponse>; + epmGetFile: jest.MockedFunction<() => string>; + epmGetStats: jest.MockedFunction<() => GetStatsResponse>; + fleetSetup: jest.MockedFunction<() => GetFleetStatusResponse>; + packagePolicyList: jest.MockedFunction<() => GetPackagePoliciesResponse>; + agentPolicyList: jest.MockedFunction<() => GetAgentPoliciesResponse>; +} + +const mockApiCalls = ( + http: MockedFleetStartServices['http'] +): MockedApi => { let inflightApiCalls = 0; const apiDoneListeners: Array<() => void> = []; const markApiCallAsHandled = async () => { @@ -663,31 +712,62 @@ On Windows, the module was tested with Nginx installed from the Chocolatey repos perPage: 100, }; + const epmGetStatsResponse: GetStatsResponse = { + response: { + agent_policy_count: 2, + }, + }; + + const mockedApiInterface: MockedApi = { + waitForApi() { + return new Promise((resolve) => { + if (inflightApiCalls > 0) { + apiDoneListeners.push(resolve); + } else { + resolve(); + } + }); + }, + responseProvider: { + epmGetInfo: jest.fn().mockReturnValue(epmPackageResponse), + epmGetFile: jest.fn().mockReturnValue(packageReadMe), + epmGetStats: jest.fn().mockReturnValue(epmGetStatsResponse), + fleetSetup: jest.fn().mockReturnValue(agentsSetupResponse), + packagePolicyList: jest.fn().mockReturnValue(packagePoliciesResponse), + agentPolicyList: jest.fn().mockReturnValue(agentPoliciesResponse), + }, + }; + http.get.mockImplementation(async (path) => { if (typeof path === 'string') { if (path === epmRouteService.getInfoPath(`nginx-0.3.7`)) { markApiCallAsHandled(); - return epmPackageResponse; + return mockedApiInterface.responseProvider.epmGetInfo(); } if (path === epmRouteService.getFilePath('/package/nginx/0.3.7/docs/README.md')) { markApiCallAsHandled(); - return packageReadMe; + return mockedApiInterface.responseProvider.epmGetFile(); } if (path === fleetSetupRouteService.getFleetSetupPath()) { markApiCallAsHandled(); - return agentsSetupResponse; + return mockedApiInterface.responseProvider.fleetSetup(); } if (path === packagePolicyRouteService.getListPath()) { markApiCallAsHandled(); - return packagePoliciesResponse; + return mockedApiInterface.responseProvider.packagePolicyList(); } if (path === agentPolicyRouteService.getListPath()) { markApiCallAsHandled(); - return agentPoliciesResponse; + return mockedApiInterface.responseProvider.agentPolicyList(); + } + + if (path === epmRouteService.getStatsPath('nginx')) { + markApiCallAsHandled(); + return mockedApiInterface.responseProvider.epmGetStats(); } const err = new Error(`API [GET ${path}] is not MOCKED!`); @@ -697,15 +777,5 @@ On Windows, the module was tested with Nginx installed from the Chocolatey repos } }); - return { - waitForApi() { - return new Promise((resolve) => { - if (inflightApiCalls > 0) { - apiDoneListeners.push(resolve); - } else { - resolve(); - } - }); - }, - }; + return mockedApiInterface; }; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/epm/screens/detail/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/epm/screens/detail/index.tsx index eee5dede16cad..a9c117222c3c2 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/epm/screens/detail/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/epm/screens/detail/index.tsx @@ -44,6 +44,7 @@ import './index.scss'; import { useUIExtension } from '../../../../hooks/use_ui_extension'; import { PLUGIN_ID } from '../../../../../../../common/constants'; import { pkgKeyFromPackageInfo } from '../../../../services/pkg_key_from_package_info'; +import { IntegrationAgentPolicyCount } from './integration_agent_policy_count'; export const DEFAULT_PANEL: DetailViewPanelName = 'overview'; @@ -239,6 +240,18 @@ export function Detail() { ), }, + ...(packageInstallStatus === 'installed' + ? [ + { isDivider: true }, + { + label: i18n.translate('xpack.fleet.epm.usedByLabel', { + defaultMessage: 'Agent Policies', + }), + 'data-test-subj': 'agentPolicyCount', + content: , + }, + ] + : []), { isDivider: true }, { content: ( @@ -264,7 +277,7 @@ export function Detail() { ), }, ].map((item, index) => ( - + {item.isDivider ?? false ? ( ) : item.label ? ( @@ -285,6 +298,7 @@ export function Detail() { handleAddIntegrationPolicyClick, hasWriteCapabilites, packageInfo, + packageInstallStatus, pkgkey, updateAvailable, ] diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/epm/screens/detail/integration_agent_policy_count.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/epm/screens/detail/integration_agent_policy_count.tsx new file mode 100644 index 0000000000000..2baf999977e3c --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/epm/screens/detail/integration_agent_policy_count.tsx @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { memo } from 'react'; +import { useGetPackageStats } from '../../../../hooks'; + +/** + * Displays a count of Agent Policies that are using the given integration + */ +export const IntegrationAgentPolicyCount = memo<{ packageName: string }>(({ packageName }) => { + const { data } = useGetPackageStats(packageName); + + return <>{data?.response.agent_policy_count ?? 0}; +}); diff --git a/x-pack/plugins/fleet/server/routes/epm/handlers.ts b/x-pack/plugins/fleet/server/routes/epm/handlers.ts index 9ccf60dc80a5f..23e3e6e7b34f1 100644 --- a/x-pack/plugins/fleet/server/routes/epm/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/epm/handlers.ts @@ -17,6 +17,7 @@ import { BulkInstallPackageInfo, BulkInstallPackagesResponse, IBulkInstallPackageHTTPError, + GetStatsResponse, } from '../../../common'; import { GetCategoriesRequestSchema, @@ -27,6 +28,7 @@ import { InstallPackageByUploadRequestSchema, DeletePackageRequestSchema, BulkUpgradePackagesFromRegistryRequestSchema, + GetStatsRequestSchema, } from '../../types'; import { BulkInstallResponse, @@ -48,6 +50,7 @@ import { splitPkgKey } from '../../services/epm/registry'; import { licenseService } from '../../services'; import { getArchiveEntry } from '../../services/epm/archive/cache'; import { getAsset } from '../../services/epm/archive/storage'; +import { getPackageUsageStats } from '../../services/epm/packages/get'; export const getCategoriesHandler: RequestHandler< undefined, @@ -196,6 +199,23 @@ export const getInfoHandler: RequestHandler> = async ( + context, + request, + response +) => { + try { + const { pkgName } = request.params; + const savedObjectsClient = context.core.savedObjects.client; + const body: GetStatsResponse = { + response: await getPackageUsageStats({ savedObjectsClient, pkgName }), + }; + return response.ok({ body }); + } catch (error) { + return defaultIngestErrorHandler({ error, response }); + } +}; + export const installPackageFromRegistryHandler: RequestHandler< TypeOf, undefined, diff --git a/x-pack/plugins/fleet/server/routes/epm/index.ts b/x-pack/plugins/fleet/server/routes/epm/index.ts index eaf61335b5e06..337903aa89993 100644 --- a/x-pack/plugins/fleet/server/routes/epm/index.ts +++ b/x-pack/plugins/fleet/server/routes/epm/index.ts @@ -15,6 +15,7 @@ import { installPackageByUploadHandler, deletePackageHandler, bulkInstallPackagesFromRegistryHandler, + getStatsHandler, } from './handlers'; import { GetCategoriesRequestSchema, @@ -25,6 +26,7 @@ import { InstallPackageByUploadRequestSchema, DeletePackageRequestSchema, BulkUpgradePackagesFromRegistryRequestSchema, + GetStatsRequestSchema, } from '../../types'; const MAX_FILE_SIZE_BYTES = 104857600; // 100MB @@ -57,6 +59,15 @@ export const registerRoutes = (router: IRouter) => { getLimitedListHandler ); + router.get( + { + path: EPM_API_ROUTES.STATS_PATTERN, + validate: GetStatsRequestSchema, + options: { tags: [`access:${PLUGIN_ID}`] }, + }, + getStatsHandler + ); + router.get( { path: EPM_API_ROUTES.FILEPATH_PATTERN, diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get.test.ts b/x-pack/plugins/fleet/server/services/epm/packages/get.test.ts new file mode 100644 index 0000000000000..7ee193b29a165 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/packages/get.test.ts @@ -0,0 +1,171 @@ +/* + * 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 { SavedObjectsClientContract, SavedObjectsFindResult } from 'kibana/server'; +import { savedObjectsClientMock } from '../../../../../../../src/core/server/mocks'; +import { PACKAGE_POLICY_SAVED_OBJECT_TYPE, PackagePolicySOAttributes } from '../../../../common'; +import { getPackageUsageStats } from './get'; + +describe('When using EPM `get` services', () => { + let soClient: jest.Mocked; + + beforeEach(() => { + soClient = savedObjectsClientMock.create(); + }); + + describe('and invoking getPackageUsageStats()', () => { + beforeEach(() => { + const savedObjects: Array> = [ + { + type: 'ingest-package-policies', + id: 'dcf83172-c38e-4501-b236-9f479da8a7d6', + attributes: { + name: 'system-3', + description: '', + namespace: 'default', + policy_id: '22222-22222-2222-2222', + enabled: true, + output_id: '', + inputs: [], + package: { name: 'system', title: 'System', version: '0.10.4' }, + revision: 1, + created_at: '2020-12-22T21:28:05.380Z', + created_by: 'elastic', + updated_at: '2020-12-22T21:28:05.380Z', + updated_by: 'elastic', + }, + references: [], + migrationVersion: { 'ingest-package-policies': '7.11.0' }, + updated_at: '2020-12-22T21:28:05.383Z', + version: 'WzE1NTAsMV0=', + score: 0, + }, + { + type: 'ingest-package-policies', + id: '5b61eb5c-d94c-48a6-a17c-b0d1f7c65336', + attributes: { + name: 'system-1', + namespace: 'default', + package: { name: 'system', title: 'System', version: '0.10.4' }, + enabled: true, + policy_id: '11111-111111-11111-11111', // << duplicate id with plicy below + output_id: 'ca111b80-43c1-11eb-84bf-7177b74381c5', + inputs: [], + revision: 1, + created_at: '2020-12-21T19:22:04.902Z', + created_by: 'system', + updated_at: '2020-12-21T19:22:04.902Z', + updated_by: 'system', + }, + references: [], + migrationVersion: { 'ingest-package-policies': '7.11.0' }, + updated_at: '2020-12-21T19:22:04.905Z', + version: 'WzIxNSwxXQ==', + score: 0, + }, + { + type: 'ingest-package-policies', + id: 'dcf83172-c38e-4501-b236-9f479da8a7d6', + attributes: { + name: 'system-2', + description: '', + namespace: 'default', + policy_id: '11111-111111-11111-11111', + enabled: true, + output_id: '', + inputs: [], + package: { name: 'system', title: 'System', version: '0.10.4' }, + revision: 1, + created_at: '2020-12-22T21:28:05.380Z', + created_by: 'elastic', + updated_at: '2020-12-22T21:28:05.380Z', + updated_by: 'elastic', + }, + references: [], + migrationVersion: { 'ingest-package-policies': '7.11.0' }, + updated_at: '2020-12-22T21:28:05.383Z', + version: 'WzE1NTAsMV0=', + score: 0, + }, + { + type: 'ingest-package-policies', + id: 'dcf83172-c38e-4501-b236-9f479da8a7d6', + attributes: { + name: 'system-4', + description: '', + namespace: 'default', + policy_id: '33333-33333-333333-333333', + enabled: true, + output_id: '', + inputs: [], + package: { name: 'system', title: 'System', version: '0.10.4' }, + revision: 1, + created_at: '2020-12-22T21:28:05.380Z', + created_by: 'elastic', + updated_at: '2020-12-22T21:28:05.380Z', + updated_by: 'elastic', + }, + references: [], + migrationVersion: { 'ingest-package-policies': '7.11.0' }, + updated_at: '2020-12-22T21:28:05.383Z', + version: 'WzE1NTAsMV0=', + score: 0, + }, + ]; + soClient.find.mockImplementation(async ({ page = 1, perPage = 20 }) => { + let savedObjectsResponse: typeof savedObjects; + + switch (page) { + case 1: + savedObjectsResponse = [savedObjects[0]]; + break; + case 2: + savedObjectsResponse = savedObjects.slice(1); + break; + default: + savedObjectsResponse = []; + } + + return { + page, + per_page: perPage, + total: 1500, + saved_objects: savedObjectsResponse, + }; + }); + }); + + it('should query and paginate SO using package name as filter', async () => { + await getPackageUsageStats({ savedObjectsClient: soClient, pkgName: 'system' }); + expect(soClient.find).toHaveBeenNthCalledWith(1, { + type: PACKAGE_POLICY_SAVED_OBJECT_TYPE, + perPage: 1000, + page: 1, + filter: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.attributes.package.name: system`, + }); + expect(soClient.find).toHaveBeenNthCalledWith(2, { + type: PACKAGE_POLICY_SAVED_OBJECT_TYPE, + perPage: 1000, + page: 2, + filter: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.attributes.package.name: system`, + }); + expect(soClient.find).toHaveBeenNthCalledWith(3, { + type: PACKAGE_POLICY_SAVED_OBJECT_TYPE, + perPage: 1000, + page: 3, + filter: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.attributes.package.name: system`, + }); + }); + + it('should return count of unique agent policies', async () => { + expect( + await getPackageUsageStats({ savedObjectsClient: soClient, pkgName: 'system' }) + ).toEqual({ + agent_policy_count: 3, + }); + }); + }); +}); diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get.ts b/x-pack/plugins/fleet/server/services/epm/packages/get.ts index f59b7a8484035..07d651668409d 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/get.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/get.ts @@ -5,7 +5,13 @@ */ import { SavedObjectsClientContract, SavedObjectsFindOptions } from 'src/core/server'; -import { isPackageLimited, installationStatuses } from '../../../../common'; +import { + isPackageLimited, + installationStatuses, + PackageUsageStats, + PackagePolicySOAttributes, + PACKAGE_POLICY_SAVED_OBJECT_TYPE, +} from '../../../../common'; import { PACKAGES_SAVED_OBJECT_TYPE } from '../../../constants'; import { ArchivePackage, RegistryPackage, EpmPackageAdditions } from '../../../../common/types'; import { Installation, PackageInfo, KibanaAssetType } from '../../../types'; @@ -13,6 +19,7 @@ import * as Registry from '../registry'; import { createInstallableFrom, isRequiredPackage } from './index'; import { getEsPackage } from '../archive/storage'; import { getArchivePackage } from '../archive'; +import { normalizeKuery } from '../../saved_object'; export { getFile, SearchParams } from '../registry'; @@ -116,6 +123,43 @@ export async function getPackageInfo(options: { return createInstallableFrom(updated, savedObject); } +export const getPackageUsageStats = async ({ + savedObjectsClient, + pkgName, +}: { + savedObjectsClient: SavedObjectsClientContract; + pkgName: string; +}): Promise => { + const filter = normalizeKuery( + PACKAGE_POLICY_SAVED_OBJECT_TYPE, + `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: ${pkgName}` + ); + const agentPolicyCount = new Set(); + let page = 1; + let hasMore = true; + + while (hasMore) { + // using saved Objects client directly, instead of the `list()` method of `package_policy` service + // in order to not cause a circular dependency (package policy service imports from this module) + const packagePolicies = await savedObjectsClient.find({ + type: PACKAGE_POLICY_SAVED_OBJECT_TYPE, + perPage: 1000, + page: page++, + filter, + }); + + for (let index = 0, total = packagePolicies.saved_objects.length; index < total; index++) { + agentPolicyCount.add(packagePolicies.saved_objects[index].attributes.policy_id); + } + + hasMore = packagePolicies.saved_objects.length > 0; + } + + return { + agent_policy_count: agentPolicyCount.size, + }; +}; + interface PackageResponse { paths: string[]; packageInfo: ArchivePackage | RegistryPackage; diff --git a/x-pack/plugins/fleet/server/types/rest_spec/epm.ts b/x-pack/plugins/fleet/server/types/rest_spec/epm.ts index 5d2a078374854..1947a6146c955 100644 --- a/x-pack/plugins/fleet/server/types/rest_spec/epm.ts +++ b/x-pack/plugins/fleet/server/types/rest_spec/epm.ts @@ -32,6 +32,12 @@ export const GetInfoRequestSchema = { }), }; +export const GetStatsRequestSchema = { + params: schema.object({ + pkgName: schema.string(), + }), +}; + export const InstallPackageFromRegistryRequestSchema = { params: schema.object({ pkgkey: schema.string(), From d3303f28bb242c6545ca3db639b6d0d41168cc6d Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Tue, 12 Jan 2021 14:51:04 +0100 Subject: [PATCH 34/64] [Search] Search Sessions with relative time range (#84405) --- ...ugins-data-public.datapublicpluginstart.md | 1 + ...ublic.datapublicpluginstart.nowprovider.md | 11 ++ .../public/application/dashboard_app.tsx | 6 +- .../application/lib/session_restoration.ts | 9 +- .../common/query/timefilter/get_time.test.ts | 17 ++- .../data/common/query/timefilter/get_time.ts | 11 ++ .../search/expressions/esaggs/esaggs_fn.ts | 4 +- .../expressions/esaggs/request_handler.ts | 7 +- src/plugins/data/public/mocks.ts | 2 + src/plugins/data/public/now_provider/index.ts | 24 ++++ .../lib/get_force_now_from_url.test.ts | 50 ++++++++ .../lib/get_force_now_from_url.ts} | 17 ++- .../data/public/now_provider/lib/index.ts | 20 +++ .../mocks.ts} | 22 ++-- .../public/now_provider/now_provider.test.ts | 55 ++++++++ .../data/public/now_provider/now_provider.ts | 50 ++++++++ src/plugins/data/public/plugin.ts | 18 ++- src/plugins/data/public/public.api.md | 6 +- .../data/public/query/query_service.ts | 6 +- .../state_sync/connect_to_query_state.test.ts | 4 + .../state_sync/sync_state_with_url.test.ts | 2 + .../query/timefilter/timefilter.test.ts | 21 +--- .../public/query/timefilter/timefilter.ts | 24 ++-- .../timefilter/timefilter_service.mock.ts | 1 + .../query/timefilter/timefilter_service.ts | 5 +- .../public/search/aggs/aggs_service.test.ts | 2 + .../data/public/search/aggs/aggs_service.ts | 11 +- .../data/public/search/expressions/esaggs.ts | 5 +- .../data/public/search/search_service.ts | 8 +- .../session/search_session_state.test.ts | 2 + .../search/session/search_session_state.ts | 20 ++- .../search/session/session_service.test.ts | 7 ++ .../public/search/session/session_service.ts | 53 +++++--- src/plugins/data/public/types.ts | 3 + .../application/angular/discover_state.ts | 9 +- .../embeddable/search_embeddable.ts | 12 +- .../public/embeddable/visualize_embeddable.ts | 6 - .../components/visualize_top_nav.tsx | 11 ++ .../services/dashboard/panel_actions.ts | 11 ++ .../embeddable/embeddable.test.tsx | 54 +------- .../embeddable/embeddable.tsx | 6 - .../kibana/__mocks__/use_timefilter.ts | 31 +---- .../dashboard/async_search/async_search.ts | 71 ++--------- .../get_search_session_id_by_panel.ts | 22 ---- .../apps/dashboard/async_search/index.ts | 2 + .../async_search/send_to_background.ts | 83 ++++++++++++ .../send_to_background_relative_time.ts | 119 ++++++++++++++++++ .../async_search/sessions_in_space.ts | 7 +- 48 files changed, 672 insertions(+), 276 deletions(-) create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.datapublicpluginstart.nowprovider.md create mode 100644 src/plugins/data/public/now_provider/index.ts create mode 100644 src/plugins/data/public/now_provider/lib/get_force_now_from_url.test.ts rename src/plugins/data/public/{query/timefilter/lib/parse_querystring.ts => now_provider/lib/get_force_now_from_url.ts} (74%) create mode 100644 src/plugins/data/public/now_provider/lib/index.ts rename src/plugins/data/public/{query/timefilter/lib/get_force_now.ts => now_provider/mocks.ts} (67%) create mode 100644 src/plugins/data/public/now_provider/now_provider.test.ts create mode 100644 src/plugins/data/public/now_provider/now_provider.ts delete mode 100644 x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/get_search_session_id_by_panel.ts create mode 100644 x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/send_to_background.ts create mode 100644 x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/send_to_background_relative_time.ts diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.datapublicpluginstart.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.datapublicpluginstart.md index 7bae0bca701bf..c7810b18c55a9 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.datapublicpluginstart.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.datapublicpluginstart.md @@ -20,6 +20,7 @@ export interface DataPublicPluginStart | [autocomplete](./kibana-plugin-plugins-data-public.datapublicpluginstart.autocomplete.md) | AutocompleteStart | autocomplete service [AutocompleteStart](./kibana-plugin-plugins-data-public.autocompletestart.md) | | [fieldFormats](./kibana-plugin-plugins-data-public.datapublicpluginstart.fieldformats.md) | FieldFormatsStart | field formats service [FieldFormatsStart](./kibana-plugin-plugins-data-public.fieldformatsstart.md) | | [indexPatterns](./kibana-plugin-plugins-data-public.datapublicpluginstart.indexpatterns.md) | IndexPatternsContract | index patterns service [IndexPatternsContract](./kibana-plugin-plugins-data-public.indexpatternscontract.md) | +| [nowProvider](./kibana-plugin-plugins-data-public.datapublicpluginstart.nowprovider.md) | NowProviderPublicContract | | | [query](./kibana-plugin-plugins-data-public.datapublicpluginstart.query.md) | QueryStart | query service [QueryStart](./kibana-plugin-plugins-data-public.querystart.md) | | [search](./kibana-plugin-plugins-data-public.datapublicpluginstart.search.md) | ISearchStart | search service [ISearchStart](./kibana-plugin-plugins-data-public.isearchstart.md) | | [ui](./kibana-plugin-plugins-data-public.datapublicpluginstart.ui.md) | DataPublicPluginStartUi | prewired UI components [DataPublicPluginStartUi](./kibana-plugin-plugins-data-public.datapublicpluginstartui.md) | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.datapublicpluginstart.nowprovider.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.datapublicpluginstart.nowprovider.md new file mode 100644 index 0000000000000..4a93c25e28815 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.datapublicpluginstart.nowprovider.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [DataPublicPluginStart](./kibana-plugin-plugins-data-public.datapublicpluginstart.md) > [nowProvider](./kibana-plugin-plugins-data-public.datapublicpluginstart.nowprovider.md) + +## DataPublicPluginStart.nowProvider property + +Signature: + +```typescript +nowProvider: NowProviderPublicContract; +``` diff --git a/src/plugins/dashboard/public/application/dashboard_app.tsx b/src/plugins/dashboard/public/application/dashboard_app.tsx index f33383427342b..8f4bc8bc6ef1a 100644 --- a/src/plugins/dashboard/public/application/dashboard_app.tsx +++ b/src/plugins/dashboard/public/application/dashboard_app.tsx @@ -173,10 +173,14 @@ export function DashboardApp({ ).subscribe(() => refreshDashboardContainer()) ); subscriptions.add( - data.search.session.onRefresh$.subscribe(() => { + merge( + data.search.session.onRefresh$, + data.query.timefilter.timefilter.getAutoRefreshFetch$() + ).subscribe(() => { setLastReloadTime(() => new Date().getTime()); }) ); + dashboardStateManager.registerChangeListener(() => { // we aren't checking dirty state because there are changes the container needs to know about // that won't make the dashboard "dirty" - like a view mode change. diff --git a/src/plugins/dashboard/public/application/lib/session_restoration.ts b/src/plugins/dashboard/public/application/lib/session_restoration.ts index 5f05fa122e161..890b81b5418be 100644 --- a/src/plugins/dashboard/public/application/lib/session_restoration.ts +++ b/src/plugins/dashboard/public/application/lib/session_restoration.ts @@ -43,17 +43,22 @@ function getUrlGeneratorState({ data, getAppState, getDashboardId, - forceAbsoluteTime, // TODO: not implemented + forceAbsoluteTime, }: { data: DataPublicPluginStart; getAppState: () => DashboardAppState; getDashboardId: () => string; + /** + * Can force time range from time filter to convert from relative to absolute time range + */ forceAbsoluteTime: boolean; }): DashboardUrlGeneratorState { const appState = getAppState(); return { dashboardId: getDashboardId(), - timeRange: data.query.timefilter.timefilter.getTime(), + timeRange: forceAbsoluteTime + ? data.query.timefilter.timefilter.getAbsoluteTime() + : data.query.timefilter.timefilter.getTime(), filters: data.query.filterManager.getFilters(), query: data.query.queryString.formatQuery(appState.query), savedQuery: appState.savedQuery, diff --git a/src/plugins/data/common/query/timefilter/get_time.test.ts b/src/plugins/data/common/query/timefilter/get_time.test.ts index 4dba157a6f554..5b77153136761 100644 --- a/src/plugins/data/common/query/timefilter/get_time.test.ts +++ b/src/plugins/data/common/query/timefilter/get_time.test.ts @@ -19,7 +19,7 @@ import moment from 'moment'; import sinon from 'sinon'; -import { getTime } from './get_time'; +import { getTime, getAbsoluteTimeRange } from './get_time'; describe('get_time', () => { describe('getTime', () => { @@ -90,4 +90,19 @@ describe('get_time', () => { clock.restore(); }); }); + describe('getAbsoluteTimeRange', () => { + test('should forward absolute timerange as is', () => { + const from = '2000-01-01T00:00:00.000Z'; + const to = '2000-02-01T00:00:00.000Z'; + expect(getAbsoluteTimeRange({ from, to })).toEqual({ from, to }); + }); + + test('should convert relative to absolute', () => { + const clock = sinon.useFakeTimers(moment.utc([2000, 1, 0, 0, 0, 0, 0]).valueOf()); + const from = '2000-01-01T00:00:00.000Z'; + const to = moment.utc(clock.now).toISOString(); + expect(getAbsoluteTimeRange({ from, to: 'now' })).toEqual({ from, to }); + clock.restore(); + }); + }); }); diff --git a/src/plugins/data/common/query/timefilter/get_time.ts b/src/plugins/data/common/query/timefilter/get_time.ts index 6e4eda95accc7..bb7b5760240b7 100644 --- a/src/plugins/data/common/query/timefilter/get_time.ts +++ b/src/plugins/data/common/query/timefilter/get_time.ts @@ -34,6 +34,17 @@ export function calculateBounds( }; } +export function getAbsoluteTimeRange( + timeRange: TimeRange, + { forceNow }: { forceNow?: Date } = {} +): TimeRange { + const { min, max } = calculateBounds(timeRange, { forceNow }); + return { + from: min ? min.toISOString() : timeRange.from, + to: max ? max.toISOString() : timeRange.to, + }; +} + export function getTime( indexPattern: IIndexPattern | undefined, timeRange: TimeRange, diff --git a/src/plugins/data/common/search/expressions/esaggs/esaggs_fn.ts b/src/plugins/data/common/search/expressions/esaggs/esaggs_fn.ts index 2274fcfd6b8d5..e9bf03af192ba 100644 --- a/src/plugins/data/common/search/expressions/esaggs/esaggs_fn.ts +++ b/src/plugins/data/common/search/expressions/esaggs/esaggs_fn.ts @@ -62,6 +62,7 @@ export interface EsaggsStartDependencies { deserializeFieldFormat: FormatFactory; indexPatterns: IndexPatternsContract; searchSource: ISearchStartSearchSource; + getNow?: () => Date; } /** @internal */ @@ -118,7 +119,8 @@ export async function handleEsaggsRequest( args: Arguments, params: RequestHandlerParams ): Promise { - const resolvedTimeRange = input?.timeRange && calculateBounds(input.timeRange); + const resolvedTimeRange = + input?.timeRange && calculateBounds(input.timeRange, { forceNow: params.getNow?.() }); const response = await handleRequest(params); diff --git a/src/plugins/data/common/search/expressions/esaggs/request_handler.ts b/src/plugins/data/common/search/expressions/esaggs/request_handler.ts index b773aad67c3f8..29a841b18706c 100644 --- a/src/plugins/data/common/search/expressions/esaggs/request_handler.ts +++ b/src/plugins/data/common/search/expressions/esaggs/request_handler.ts @@ -51,6 +51,7 @@ export interface RequestHandlerParams { searchSourceService: ISearchStartSearchSource; timeFields?: string[]; timeRange?: TimeRange; + getNow?: () => Date; } export const handleRequest = async ({ @@ -67,7 +68,9 @@ export const handleRequest = async ({ searchSourceService, timeFields, timeRange, + getNow, }: RequestHandlerParams) => { + const forceNow = getNow?.(); const searchSource = await searchSourceService.create(); searchSource.setField('index', indexPattern); @@ -115,7 +118,7 @@ export const handleRequest = async ({ if (timeRange && allTimeFields.length > 0) { timeFilterSearchSource.setField('filter', () => { return allTimeFields - .map((fieldName) => getTime(indexPattern, timeRange, { fieldName })) + .map((fieldName) => getTime(indexPattern, timeRange, { fieldName, forceNow })) .filter(isRangeFilter); }); } @@ -183,7 +186,7 @@ export const handleRequest = async ({ } } - const parsedTimeRange = timeRange ? calculateBounds(timeRange) : null; + const parsedTimeRange = timeRange ? calculateBounds(timeRange, { forceNow }) : null; const tabifyParams = { metricsAtAllLevels, partialRows, diff --git a/src/plugins/data/public/mocks.ts b/src/plugins/data/public/mocks.ts index 67c1ff7e09dd7..c34139caa553e 100644 --- a/src/plugins/data/public/mocks.ts +++ b/src/plugins/data/public/mocks.ts @@ -22,6 +22,7 @@ import { fieldFormatsServiceMock } from './field_formats/mocks'; import { searchServiceMock } from './search/mocks'; import { queryServiceMock } from './query/mocks'; import { AutocompleteStart, AutocompleteSetup } from './autocomplete'; +import { createNowProviderMock } from './now_provider/mocks'; export type Setup = jest.Mocked>; export type Start = jest.Mocked>; @@ -76,6 +77,7 @@ const createStartContract = (): Start => { get: jest.fn().mockReturnValue(Promise.resolve({})), clearCache: jest.fn(), } as unknown) as IndexPatternsContract, + nowProvider: createNowProviderMock(), }; }; diff --git a/src/plugins/data/public/now_provider/index.ts b/src/plugins/data/public/now_provider/index.ts new file mode 100644 index 0000000000000..662ab87dd534b --- /dev/null +++ b/src/plugins/data/public/now_provider/index.ts @@ -0,0 +1,24 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { + NowProvider, + NowProviderInternalContract, + NowProviderPublicContract, +} from './now_provider'; diff --git a/src/plugins/data/public/now_provider/lib/get_force_now_from_url.test.ts b/src/plugins/data/public/now_provider/lib/get_force_now_from_url.test.ts new file mode 100644 index 0000000000000..4e3233474b040 --- /dev/null +++ b/src/plugins/data/public/now_provider/lib/get_force_now_from_url.test.ts @@ -0,0 +1,50 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { getForceNowFromUrl } from './get_force_now_from_url'; +const originalLocation = window.location; +afterAll(() => { + window.location = originalLocation; +}); + +function mockLocation(url: string) { + // @ts-ignore + delete window.location; + // @ts-ignore + window.location = new URL(url); +} + +test('should get force now from URL', () => { + const dateString = '1999-01-01T00:00:00.000Z'; + mockLocation(`https://elastic.co/?forceNow=${dateString}`); + + expect(getForceNowFromUrl()).toEqual(new Date(dateString)); +}); + +test('should throw if force now is invalid', () => { + const dateString = 'invalid-date'; + mockLocation(`https://elastic.co/?forceNow=${dateString}`); + + expect(() => getForceNowFromUrl()).toThrowError(); +}); + +test('should return undefined if no forceNow', () => { + mockLocation(`https://elastic.co/`); + expect(getForceNowFromUrl()).toBe(undefined); +}); diff --git a/src/plugins/data/public/query/timefilter/lib/parse_querystring.ts b/src/plugins/data/public/now_provider/lib/get_force_now_from_url.ts similarity index 74% rename from src/plugins/data/public/query/timefilter/lib/parse_querystring.ts rename to src/plugins/data/public/now_provider/lib/get_force_now_from_url.ts index 5982bfd0bd276..906eec1ab143e 100644 --- a/src/plugins/data/public/query/timefilter/lib/parse_querystring.ts +++ b/src/plugins/data/public/now_provider/lib/get_force_now_from_url.ts @@ -16,10 +16,25 @@ * specific language governing permissions and limitations * under the License. */ + import { parse } from 'query-string'; /** @internal */ -export function parseQueryString() { +export function getForceNowFromUrl(): Date | undefined { + const forceNow = parseQueryString().forceNow as string; + if (!forceNow) { + return; + } + + const ts = Date.parse(forceNow); + if (isNaN(ts)) { + throw new Error(`forceNow query parameter, ${forceNow}, can't be parsed by Date.parse`); + } + return new Date(ts); +} + +/** @internal */ +function parseQueryString() { // window.location.search is an empty string // get search from href const hrefSplit = window.location.href.split('?'); diff --git a/src/plugins/data/public/now_provider/lib/index.ts b/src/plugins/data/public/now_provider/lib/index.ts new file mode 100644 index 0000000000000..990db5ae3c77c --- /dev/null +++ b/src/plugins/data/public/now_provider/lib/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { getForceNowFromUrl } from './get_force_now_from_url'; diff --git a/src/plugins/data/public/query/timefilter/lib/get_force_now.ts b/src/plugins/data/public/now_provider/mocks.ts similarity index 67% rename from src/plugins/data/public/query/timefilter/lib/get_force_now.ts rename to src/plugins/data/public/now_provider/mocks.ts index fe68656f0c3aa..1021d2b48cfe5 100644 --- a/src/plugins/data/public/query/timefilter/lib/get_force_now.ts +++ b/src/plugins/data/public/now_provider/mocks.ts @@ -17,18 +17,12 @@ * under the License. */ -import { parseQueryString } from './parse_querystring'; +import { NowProviderInternalContract } from './now_provider'; -/** @internal */ -export function getForceNow() { - const forceNow = parseQueryString().forceNow as string; - if (!forceNow) { - return; - } - - const ticks = Date.parse(forceNow); - if (isNaN(ticks)) { - throw new Error(`forceNow query parameter, ${forceNow}, can't be parsed by Date.parse`); - } - return new Date(ticks); -} +export const createNowProviderMock = (): jest.Mocked => { + return { + get: jest.fn(() => new Date()), + set: jest.fn(), + reset: jest.fn(), + }; +}; diff --git a/src/plugins/data/public/now_provider/now_provider.test.ts b/src/plugins/data/public/now_provider/now_provider.test.ts new file mode 100644 index 0000000000000..e557065ff2b67 --- /dev/null +++ b/src/plugins/data/public/now_provider/now_provider.test.ts @@ -0,0 +1,55 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { NowProvider, NowProviderInternalContract } from './now_provider'; + +let mockDateFromUrl: undefined | Date; +let nowProvider: NowProviderInternalContract; + +jest.mock('./lib', () => ({ + // @ts-ignore + ...jest.requireActual('./lib'), + getForceNowFromUrl: () => mockDateFromUrl, +})); + +beforeEach(() => { + nowProvider = new NowProvider(); +}); +afterEach(() => { + mockDateFromUrl = undefined; +}); + +test('should return Date.now() by default', async () => { + const now = Date.now(); + await new Promise((r) => setTimeout(r, 10)); + expect(nowProvider.get().getTime()).toBeGreaterThan(now); +}); + +test('should forceNow from URL', async () => { + mockDateFromUrl = new Date('1999-01-01T00:00:00.000Z'); + nowProvider = new NowProvider(); + expect(nowProvider.get()).toEqual(mockDateFromUrl); +}); + +test('should forceNow from URL if custom now is set', async () => { + mockDateFromUrl = new Date('1999-01-01T00:00:00.000Z'); + nowProvider = new NowProvider(); + nowProvider.set(new Date()); + expect(nowProvider.get()).toEqual(mockDateFromUrl); +}); diff --git a/src/plugins/data/public/now_provider/now_provider.ts b/src/plugins/data/public/now_provider/now_provider.ts new file mode 100644 index 0000000000000..a55fa691ef1da --- /dev/null +++ b/src/plugins/data/public/now_provider/now_provider.ts @@ -0,0 +1,50 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { PublicMethodsOf } from '@kbn/utility-types'; +import { getForceNowFromUrl } from './lib'; + +export type NowProviderInternalContract = PublicMethodsOf; +export type NowProviderPublicContract = Pick; + +/** + * Used to synchronize time between parallel searches with relative time range that rely on `now`. + */ +export class NowProvider { + // TODO: service shouldn't access params in the URL + // instead it should be handled by apps + private readonly nowFromUrl = getForceNowFromUrl(); + private now?: Date; + + constructor() {} + + get(): Date { + if (this.nowFromUrl) return this.nowFromUrl; // now forced from URL always takes precedence + if (this.now) return this.now; + return new Date(); + } + + set(now: Date) { + this.now = now; + } + + reset() { + this.now = undefined; + } +} diff --git a/src/plugins/data/public/plugin.ts b/src/plugins/data/public/plugin.ts index 43abe84950fdb..aabf3136e6159 100644 --- a/src/plugins/data/public/plugin.ts +++ b/src/plugins/data/public/plugin.ts @@ -61,6 +61,7 @@ import { SavedObjectsClientPublicToCommon } from './index_patterns'; import { getIndexPatternLoad } from './index_patterns/expressions'; import { UsageCollectionSetup } from '../../usage_collection/public'; import { getTableViewDescription } from './utils/table_inspector_view'; +import { NowProvider, NowProviderInternalContract } from './now_provider'; export class DataPublicPlugin implements @@ -76,6 +77,7 @@ export class DataPublicPlugin private readonly queryService: QueryService; private readonly storage: IStorageWrapper; private usageCollection: UsageCollectionSetup | undefined; + private readonly nowProvider: NowProviderInternalContract; constructor(initializerContext: PluginInitializerContext) { this.searchService = new SearchService(initializerContext); @@ -83,6 +85,7 @@ export class DataPublicPlugin this.fieldFormatsService = new FieldFormatsService(); this.autocomplete = new AutocompleteService(initializerContext); this.storage = new Storage(window.localStorage); + this.nowProvider = new NowProvider(); } public setup( @@ -95,9 +98,17 @@ export class DataPublicPlugin this.usageCollection = usageCollection; + const searchService = this.searchService.setup(core, { + bfetch, + usageCollection, + expressions, + nowProvider: this.nowProvider, + }); + const queryService = this.queryService.setup({ uiSettings: core.uiSettings, storage: this.storage, + nowProvider: this.nowProvider, }); uiActions.registerTrigger(applyFilterTrigger); @@ -120,12 +131,6 @@ export class DataPublicPlugin })) ); - const searchService = this.searchService.setup(core, { - bfetch, - usageCollection, - expressions, - }); - inspector.registerView( getTableViewDescription(() => ({ uiActions: startServices().plugins.uiActions, @@ -195,6 +200,7 @@ export class DataPublicPlugin indexPatterns, query, search, + nowProvider: this.nowProvider, }; const SearchBar = createSearchBar({ diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 27a40b4e5ffcb..935cb945678de 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -580,6 +580,10 @@ export interface DataPublicPluginStart { autocomplete: AutocompleteStart; fieldFormats: FieldFormatsStart; indexPatterns: IndexPatternsContract; + // Warning: (ae-forgotten-export) The symbol "NowProviderPublicContract" needs to be exported by the entry point index.d.ts + // + // (undocumented) + nowProvider: NowProviderPublicContract; query: QueryStart; search: ISearchStart; ui: DataPublicPluginStartUi; @@ -2620,7 +2624,7 @@ export const UI_SETTINGS: { // src/plugins/data/public/index.ts:433:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:436:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts // src/plugins/data/public/query/state_sync/connect_to_query_state.ts:45:5 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/search/session/session_service.ts:50:5 - (ae-forgotten-export) The symbol "UrlGeneratorStateMapping" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/search/session/session_service.ts:51:5 - (ae-forgotten-export) The symbol "UrlGeneratorStateMapping" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/src/plugins/data/public/query/query_service.ts b/src/plugins/data/public/query/query_service.ts index fe7fdcbb1d113..e5f681549b06e 100644 --- a/src/plugins/data/public/query/query_service.ts +++ b/src/plugins/data/public/query/query_service.ts @@ -28,6 +28,7 @@ import { createQueryStateObservable } from './state_sync/create_global_query_obs import { QueryStringManager, QueryStringContract } from './query_string'; import { buildEsQuery, getEsQueryConfig } from '../../common'; import { getUiSettings } from '../services'; +import { NowProviderInternalContract } from '../now_provider'; import { IndexPattern } from '..'; /** @@ -38,6 +39,7 @@ import { IndexPattern } from '..'; interface QueryServiceSetupDependencies { storage: IStorageWrapper; uiSettings: IUiSettingsClient; + nowProvider: NowProviderInternalContract; } interface QueryServiceStartDependencies { @@ -53,10 +55,10 @@ export class QueryService { state$!: ReturnType; - public setup({ storage, uiSettings }: QueryServiceSetupDependencies) { + public setup({ storage, uiSettings, nowProvider }: QueryServiceSetupDependencies) { this.filterManager = new FilterManager(uiSettings); - const timefilterService = new TimefilterService(); + const timefilterService = new TimefilterService(nowProvider); this.timefilter = timefilterService.setup({ uiSettings, storage, diff --git a/src/plugins/data/public/query/state_sync/connect_to_query_state.test.ts b/src/plugins/data/public/query/state_sync/connect_to_query_state.test.ts index c970dd521c142..3ad1f3daa992b 100644 --- a/src/plugins/data/public/query/state_sync/connect_to_query_state.test.ts +++ b/src/plugins/data/public/query/state_sync/connect_to_query_state.test.ts @@ -28,6 +28,7 @@ import { StubBrowserStorage } from '@kbn/test/jest'; import { connectToQueryState } from './connect_to_query_state'; import { TimefilterContract } from '../timefilter'; import { QueryState } from './types'; +import { createNowProviderMock } from '../../now_provider/mocks'; const connectToQueryGlobalState = (query: QueryStart, state: BaseStateContainer) => connectToQueryState(query, state, { @@ -79,6 +80,7 @@ describe('connect_to_global_state', () => { queryService.setup({ uiSettings: setupMock.uiSettings, storage: new Storage(new StubBrowserStorage()), + nowProvider: createNowProviderMock(), }); queryServiceStart = queryService.start({ uiSettings: setupMock.uiSettings, @@ -312,6 +314,7 @@ describe('connect_to_app_state', () => { queryService.setup({ uiSettings: setupMock.uiSettings, storage: new Storage(new StubBrowserStorage()), + nowProvider: createNowProviderMock(), }); queryServiceStart = queryService.start({ uiSettings: setupMock.uiSettings, @@ -490,6 +493,7 @@ describe('filters with different state', () => { queryService.setup({ uiSettings: setupMock.uiSettings, storage: new Storage(new StubBrowserStorage()), + nowProvider: createNowProviderMock(), }); queryServiceStart = queryService.start({ uiSettings: setupMock.uiSettings, diff --git a/src/plugins/data/public/query/state_sync/sync_state_with_url.test.ts b/src/plugins/data/public/query/state_sync/sync_state_with_url.test.ts index 47af09bfc7c0e..129a145ee0693 100644 --- a/src/plugins/data/public/query/state_sync/sync_state_with_url.test.ts +++ b/src/plugins/data/public/query/state_sync/sync_state_with_url.test.ts @@ -33,6 +33,7 @@ import { StubBrowserStorage } from '@kbn/test/jest'; import { TimefilterContract } from '../timefilter'; import { syncQueryStateWithUrl } from './sync_state_with_url'; import { QueryState } from './types'; +import { createNowProviderMock } from '../../now_provider/mocks'; const setupMock = coreMock.createSetup(); const startMock = coreMock.createStart(); @@ -73,6 +74,7 @@ describe('sync_query_state_with_url', () => { queryService.setup({ uiSettings: setupMock.uiSettings, storage: new Storage(new StubBrowserStorage()), + nowProvider: createNowProviderMock(), }); queryServiceStart = queryService.start({ uiSettings: startMock.uiSettings, diff --git a/src/plugins/data/public/query/timefilter/timefilter.test.ts b/src/plugins/data/public/query/timefilter/timefilter.test.ts index 6c1a4eff786f6..d8dfed002ea80 100644 --- a/src/plugins/data/public/query/timefilter/timefilter.test.ts +++ b/src/plugins/data/public/query/timefilter/timefilter.test.ts @@ -19,21 +19,12 @@ jest.useFakeTimers(); -jest.mock('./lib/parse_querystring', () => ({ - parseQueryString: () => { - return { - // Can not access local variable from within a mock - // @ts-ignore - forceNow: global.nowTime, - }; - }, -})); - import sinon from 'sinon'; import moment from 'moment'; import { Timefilter } from './timefilter'; import { Subscription } from 'rxjs'; import { TimeRange, RefreshInterval } from '../../../common'; +import { createNowProviderMock } from '../../now_provider/mocks'; import { timefilterServiceMock } from './timefilter_service.mock'; const timefilterSetupMock = timefilterServiceMock.createSetupContract(); @@ -42,16 +33,16 @@ const timefilterConfig = { timeDefaults: { from: 'now-15m', to: 'now' }, refreshIntervalDefaults: { pause: false, value: 0 }, }; -const timefilter = new Timefilter(timefilterConfig, timefilterSetupMock.history); + +const nowProviderMock = createNowProviderMock(); +const timefilter = new Timefilter(timefilterConfig, timefilterSetupMock.history, nowProviderMock); function stubNowTime(nowTime: any) { - // @ts-ignore - global.nowTime = nowTime; + nowProviderMock.get.mockImplementation(() => (nowTime ? new Date(nowTime) : new Date())); } function clearNowTimeStub() { - // @ts-ignore - delete global.nowTime; + nowProviderMock.get.mockReset(); } test('isTimeTouched is initially set to false', () => { diff --git a/src/plugins/data/public/query/timefilter/timefilter.ts b/src/plugins/data/public/query/timefilter/timefilter.ts index 7278ceaaddcce..3ee2a3962e8ff 100644 --- a/src/plugins/data/public/query/timefilter/timefilter.ts +++ b/src/plugins/data/public/query/timefilter/timefilter.ts @@ -22,10 +22,11 @@ import { Subject, BehaviorSubject } from 'rxjs'; import moment from 'moment'; import { PublicMethodsOf } from '@kbn/utility-types'; import { areRefreshIntervalsDifferent, areTimeRangesDifferent } from './lib/diff_time_picker_vals'; -import { getForceNow } from './lib/get_force_now'; import { TimefilterConfig, InputTimeRange, TimeRangeBounds } from './types'; +import { NowProviderInternalContract } from '../../now_provider'; import { calculateBounds, + getAbsoluteTimeRange, getTime, IIndexPattern, RefreshInterval, @@ -60,7 +61,11 @@ export class Timefilter { private readonly timeDefaults: TimeRange; private readonly refreshIntervalDefaults: RefreshInterval; - constructor(config: TimefilterConfig, timeHistory: TimeHistoryContract) { + constructor( + config: TimefilterConfig, + timeHistory: TimeHistoryContract, + private readonly nowProvider: NowProviderInternalContract + ) { this._history = timeHistory; this.timeDefaults = config.timeDefaults; this.refreshIntervalDefaults = config.refreshIntervalDefaults; @@ -109,6 +114,13 @@ export class Timefilter { }; }; + /** + * Same as {@link getTime}, but also converts relative time range to absolute time range + */ + public getAbsoluteTime() { + return getAbsoluteTimeRange(this._time, { forceNow: this.nowProvider.get() }); + } + /** * Updates timefilter time. * Emits 'timeUpdate' and 'fetch' events when time changes @@ -177,7 +189,7 @@ export class Timefilter { public createFilter = (indexPattern: IIndexPattern, timeRange?: TimeRange) => { return getTime(indexPattern, timeRange ? timeRange : this._time, { - forceNow: this.getForceNow(), + forceNow: this.nowProvider.get(), }); }; @@ -186,7 +198,7 @@ export class Timefilter { } public calculateBounds(timeRange: TimeRange): TimeRangeBounds { - return calculateBounds(timeRange, { forceNow: this.getForceNow() }); + return calculateBounds(timeRange, { forceNow: this.nowProvider.get() }); } public getActiveBounds(): TimeRangeBounds | undefined { @@ -234,10 +246,6 @@ export class Timefilter { public getRefreshIntervalDefaults(): RefreshInterval { return _.cloneDeep(this.refreshIntervalDefaults); } - - private getForceNow = () => { - return getForceNow(); - }; } export type TimefilterContract = PublicMethodsOf; diff --git a/src/plugins/data/public/query/timefilter/timefilter_service.mock.ts b/src/plugins/data/public/query/timefilter/timefilter_service.mock.ts index 9f1c64a1739a5..72ff49b9178fc 100644 --- a/src/plugins/data/public/query/timefilter/timefilter_service.mock.ts +++ b/src/plugins/data/public/query/timefilter/timefilter_service.mock.ts @@ -46,6 +46,7 @@ const createSetupContractMock = () => { createFilter: jest.fn(), getRefreshIntervalDefaults: jest.fn(), getTimeDefaults: jest.fn(), + getAbsoluteTime: jest.fn(), }; const historyMock: jest.Mocked = { diff --git a/src/plugins/data/public/query/timefilter/timefilter_service.ts b/src/plugins/data/public/query/timefilter/timefilter_service.ts index 35b46de5f21b2..1f0c0345a0eae 100644 --- a/src/plugins/data/public/query/timefilter/timefilter_service.ts +++ b/src/plugins/data/public/query/timefilter/timefilter_service.ts @@ -21,6 +21,7 @@ import { IUiSettingsClient } from 'src/core/public'; import { IStorageWrapper } from 'src/plugins/kibana_utils/public'; import { TimeHistory, Timefilter, TimeHistoryContract, TimefilterContract } from './index'; import { UI_SETTINGS } from '../../../common'; +import { NowProviderInternalContract } from '../../now_provider'; /** * Filter Service @@ -33,13 +34,15 @@ export interface TimeFilterServiceDependencies { } export class TimefilterService { + constructor(private readonly nowProvider: NowProviderInternalContract) {} + public setup({ uiSettings, storage }: TimeFilterServiceDependencies): TimefilterSetup { const timefilterConfig = { timeDefaults: uiSettings.get(UI_SETTINGS.TIMEPICKER_TIME_DEFAULTS), refreshIntervalDefaults: uiSettings.get(UI_SETTINGS.TIMEPICKER_REFRESH_INTERVAL_DEFAULTS), }; const history = new TimeHistory(storage); - const timefilter = new Timefilter(timefilterConfig, history); + const timefilter = new Timefilter(timefilterConfig, history, this.nowProvider); return { timefilter, diff --git a/src/plugins/data/public/search/aggs/aggs_service.test.ts b/src/plugins/data/public/search/aggs/aggs_service.test.ts index bc4992384b0c2..86a466b699710 100644 --- a/src/plugins/data/public/search/aggs/aggs_service.test.ts +++ b/src/plugins/data/public/search/aggs/aggs_service.test.ts @@ -31,6 +31,7 @@ import { AggsStartDependencies, createGetConfig, } from './aggs_service'; +import { createNowProviderMock } from '../../now_provider/mocks'; const { uiSettings } = coreMock.createSetup(); @@ -44,6 +45,7 @@ describe('AggsService - public', () => { setupDeps = { registerFunction: expressionsPluginMock.createSetupContract().registerFunction, uiSettings, + nowProvider: createNowProviderMock(), }; startDeps = { fieldFormats: fieldFormatsServiceMock.createStartContract(), diff --git a/src/plugins/data/public/search/aggs/aggs_service.ts b/src/plugins/data/public/search/aggs/aggs_service.ts index 7b5edac0280d9..59032a8608632 100644 --- a/src/plugins/data/public/search/aggs/aggs_service.ts +++ b/src/plugins/data/public/search/aggs/aggs_service.ts @@ -22,7 +22,6 @@ import { Subscription } from 'rxjs'; import { IUiSettingsClient } from 'src/core/public'; import { ExpressionsServiceSetup } from 'src/plugins/expressions/common'; import { FieldFormatsStart } from '../../field_formats'; -import { getForceNow } from '../../query/timefilter/lib/get_force_now'; import { calculateBounds, TimeRange } from '../../../common'; import { aggsRequiredUiSettings, @@ -33,6 +32,7 @@ import { } from '../../../common/search/aggs'; import { AggsSetup, AggsStart } from './types'; import { IndexPatternsContract } from '../../index_patterns'; +import { NowProviderInternalContract } from '../../now_provider'; /** * Aggs needs synchronous access to specific uiSettings. Since settings can change @@ -63,6 +63,7 @@ export function createGetConfig( export interface AggsSetupDependencies { registerFunction: ExpressionsServiceSetup['registerFunction']; uiSettings: IUiSettingsClient; + nowProvider: NowProviderInternalContract; } /** @internal */ @@ -82,15 +83,17 @@ export class AggsService { private readonly initializedAggTypes = new Map(); private getConfig?: AggsCommonStartDependencies['getConfig']; private subscriptions: Subscription[] = []; + private nowProvider!: NowProviderInternalContract; /** - * getForceNow uses window.location, so we must have a separate implementation + * NowGetter uses window.location, so we must have a separate implementation * of calculateBounds on the client and the server. */ private calculateBounds = (timeRange: TimeRange) => - calculateBounds(timeRange, { forceNow: getForceNow() }); + calculateBounds(timeRange, { forceNow: this.nowProvider.get() }); - public setup({ registerFunction, uiSettings }: AggsSetupDependencies): AggsSetup { + public setup({ registerFunction, uiSettings, nowProvider }: AggsSetupDependencies): AggsSetup { + this.nowProvider = nowProvider; this.getConfig = createGetConfig(uiSettings, aggsRequiredUiSettings, this.subscriptions); return this.aggsCommonService.setup({ registerFunction }); diff --git a/src/plugins/data/public/search/expressions/esaggs.ts b/src/plugins/data/public/search/expressions/esaggs.ts index d8d90ea464a73..63138ee1b0454 100644 --- a/src/plugins/data/public/search/expressions/esaggs.ts +++ b/src/plugins/data/public/search/expressions/esaggs.ts @@ -53,6 +53,7 @@ export function getFunctionDefinition({ deserializeFieldFormat, indexPatterns, searchSource, + getNow, } = await getStartDependencies(); const indexPattern = await indexPatterns.create(args.index.value, true); @@ -75,6 +76,7 @@ export function getFunctionDefinition({ searchSourceService: searchSource, timeFields: args.timeFields, timeRange: get(input, 'timeRange', undefined), + getNow, }); }, }); @@ -102,12 +104,13 @@ export function getEsaggs({ return getFunctionDefinition({ getStartDependencies: async () => { const [, , self] = await getStartServices(); - const { fieldFormats, indexPatterns, search } = self; + const { fieldFormats, indexPatterns, search, nowProvider } = self; return { aggs: search.aggs, deserializeFieldFormat: fieldFormats.deserialize.bind(fieldFormats), indexPatterns, searchSource: search.searchSource, + getNow: () => nowProvider.get(), }; }, }); diff --git a/src/plugins/data/public/search/search_service.ts b/src/plugins/data/public/search/search_service.ts index 1c49de8f0ff4b..eef6190fe78c5 100644 --- a/src/plugins/data/public/search/search_service.ts +++ b/src/plugins/data/public/search/search_service.ts @@ -53,12 +53,14 @@ import { } from '../../common/search/aggs/buckets/shard_delay'; import { aggShardDelay } from '../../common/search/aggs/buckets/shard_delay_fn'; import { DataPublicPluginStart, DataStartDependencies } from '../types'; +import { NowProviderInternalContract } from '../now_provider'; /** @internal */ export interface SearchServiceSetupDependencies { bfetch: BfetchPublicSetup; expressions: ExpressionsSetup; usageCollection?: UsageCollectionSetup; + nowProvider: NowProviderInternalContract; } /** @internal */ @@ -79,7 +81,7 @@ export class SearchService implements Plugin { public setup( { http, getStartServices, notifications, uiSettings }: CoreSetup, - { bfetch, expressions, usageCollection }: SearchServiceSetupDependencies + { bfetch, expressions, usageCollection, nowProvider }: SearchServiceSetupDependencies ): ISearchSetup { this.usageCollector = createUsageCollector(getStartServices, usageCollection); @@ -87,7 +89,8 @@ export class SearchService implements Plugin { this.sessionService = new SessionService( this.initializerContext, getStartServices, - this.sessionsClient + this.sessionsClient, + nowProvider ); /** * A global object that intercepts all searches and provides convenience methods for cancelling @@ -118,6 +121,7 @@ export class SearchService implements Plugin { const aggs = this.aggsService.setup({ registerFunction: expressions.registerFunction, uiSettings, + nowProvider, }); if (this.initializerContext.config.get().search.aggs.shardDelay.enabled) { diff --git a/src/plugins/data/public/search/session/search_session_state.test.ts b/src/plugins/data/public/search/session/search_session_state.test.ts index 539fc8252b2a5..c2cb75b9a7493 100644 --- a/src/plugins/data/public/search/session/search_session_state.test.ts +++ b/src/plugins/data/public/search/session/search_session_state.test.ts @@ -31,6 +31,7 @@ describe('Session state container', () => { state.transitions.start(); expect(state.selectors.getState()).toBe(SearchSessionState.None); expect(state.get().sessionId).not.toBeUndefined(); + expect(state.get().startTime).not.toBeUndefined(); }); test('track', () => { @@ -56,6 +57,7 @@ describe('Session state container', () => { state.transitions.clear(); expect(state.selectors.getState()).toBe(SearchSessionState.None); expect(state.get().sessionId).toBeUndefined(); + expect(state.get().startTime).toBeUndefined(); }); test('cancel', () => { diff --git a/src/plugins/data/public/search/session/search_session_state.ts b/src/plugins/data/public/search/session/search_session_state.ts index 7a35a65a600d7..0894de13d53a9 100644 --- a/src/plugins/data/public/search/session/search_session_state.ts +++ b/src/plugins/data/public/search/session/search_session_state.ts @@ -105,6 +105,11 @@ export interface SessionStateInternal { * If user has explicitly canceled search requests */ isCanceled: boolean; + + /** + * Start time of current session + */ + startTime?: Date; } const createSessionDefaultState: < @@ -132,7 +137,11 @@ export interface SessionPureTransitions< } export const sessionPureTransitions: SessionPureTransitions = { - start: (state) => () => ({ ...createSessionDefaultState(), sessionId: uuid.v4() }), + start: (state) => () => ({ + ...createSessionDefaultState(), + sessionId: uuid.v4(), + startTime: new Date(), + }), restore: (state) => (sessionId: string) => ({ ...createSessionDefaultState(), sessionId, @@ -216,6 +225,7 @@ export const createSessionStateContainer = ( ): { stateContainer: SessionStateContainer; sessionState$: Observable; + sessionStartTime$: Observable; } => { const stateContainer = createStateContainer( createSessionDefaultState(), @@ -229,8 +239,16 @@ export const createSessionStateContainer = ( distinctUntilChanged(), shareReplay(1) ); + + const sessionStartTime$: Observable = stateContainer.state$.pipe( + map(() => stateContainer.get().startTime), + distinctUntilChanged(), + shareReplay(1) + ); + return { stateContainer, sessionState$, + sessionStartTime$, }; }; diff --git a/src/plugins/data/public/search/session/session_service.test.ts b/src/plugins/data/public/search/session/session_service.test.ts index cf083239b1571..aeca7b4d63da7 100644 --- a/src/plugins/data/public/search/session/session_service.test.ts +++ b/src/plugins/data/public/search/session/session_service.test.ts @@ -23,17 +23,22 @@ import { take, toArray } from 'rxjs/operators'; import { getSessionsClientMock } from './mocks'; import { BehaviorSubject } from 'rxjs'; import { SearchSessionState } from './search_session_state'; +import { createNowProviderMock } from '../../now_provider/mocks'; +import { NowProviderInternalContract } from '../../now_provider'; describe('Session service', () => { let sessionService: ISessionService; let state$: BehaviorSubject; + let nowProvider: jest.Mocked; beforeEach(() => { const initializerContext = coreMock.createPluginInitializerContext(); + nowProvider = createNowProviderMock(); sessionService = new SessionService( initializerContext, coreMock.createSetup().getStartServices, getSessionsClientMock(), + nowProvider, { freezeState: false } // needed to use mocks inside state container ); state$ = new BehaviorSubject(SearchSessionState.None); @@ -44,8 +49,10 @@ describe('Session service', () => { it('Creates and clears a session', async () => { sessionService.start(); expect(sessionService.getSessionId()).not.toBeUndefined(); + expect(nowProvider.set).toHaveBeenCalled(); sessionService.clear(); expect(sessionService.getSessionId()).toBeUndefined(); + expect(nowProvider.reset).toHaveBeenCalled(); }); it('Restores a session', async () => { diff --git a/src/plugins/data/public/search/session/session_service.ts b/src/plugins/data/public/search/session/session_service.ts index 2bbb762fcfe9f..e2185d8148708 100644 --- a/src/plugins/data/public/search/session/session_service.ts +++ b/src/plugins/data/public/search/session/session_service.ts @@ -29,6 +29,7 @@ import { SessionStateContainer, } from './search_session_state'; import { ISessionsClient } from './sessions_client'; +import { NowProviderInternalContract } from '../../now_provider'; export type ISessionService = PublicContract; @@ -60,40 +61,54 @@ export class SessionService { private readonly state: SessionStateContainer; private searchSessionInfoProvider?: SearchSessionInfoProvider; - private appChangeSubscription$?: Subscription; + private subscription = new Subscription(); private curApp?: string; constructor( initializerContext: PluginInitializerContext, getStartServices: StartServicesAccessor, private readonly sessionsClient: ISessionsClient, + private readonly nowProvider: NowProviderInternalContract, { freezeState = true }: { freezeState: boolean } = { freezeState: true } ) { - const { stateContainer, sessionState$ } = createSessionStateContainer({ + const { + stateContainer, + sessionState$, + sessionStartTime$, + } = createSessionStateContainer({ freeze: freezeState, }); this.state$ = sessionState$; this.state = stateContainer; + this.subscription.add( + sessionStartTime$.subscribe((startTime) => { + if (startTime) this.nowProvider.set(startTime); + else this.nowProvider.reset(); + }) + ); + getStartServices().then(([coreStart]) => { // Apps required to clean up their sessions before unmounting // Make sure that apps don't leave sessions open. - this.appChangeSubscription$ = coreStart.application.currentAppId$.subscribe((appName) => { - if (this.state.get().sessionId) { - const message = `Application '${this.curApp}' had an open session while navigating`; - if (initializerContext.env.mode.dev) { - // TODO: This setTimeout is necessary due to a race condition while navigating. - setTimeout(() => { - coreStart.fatalErrors.add(message); - }, 100); - } else { - // eslint-disable-next-line no-console - console.warn(message); - this.clear(); + this.subscription.add( + coreStart.application.currentAppId$.subscribe((appName) => { + if (this.state.get().sessionId) { + const message = `Application '${this.curApp}' had an open session while navigating`; + if (initializerContext.env.mode.dev) { + // TODO: This setTimeout is necessary due to a race condition while navigating. + setTimeout(() => { + coreStart.fatalErrors.add(message); + }, 100); + } else { + // eslint-disable-next-line no-console + console.warn(message); + this.clear(); + } } - } - this.curApp = appName; - }); + this.curApp = appName; + }) + ); }); } @@ -122,9 +137,7 @@ export class SessionService { } public destroy() { - if (this.appChangeSubscription$) { - this.appChangeSubscription$.unsubscribe(); - } + this.subscription.unsubscribe(); this.clear(); } diff --git a/src/plugins/data/public/types.ts b/src/plugins/data/public/types.ts index c7b66acfc6c7a..e38cabe313b6c 100644 --- a/src/plugins/data/public/types.ts +++ b/src/plugins/data/public/types.ts @@ -32,6 +32,7 @@ import { IndexPatternsContract } from './index_patterns'; import { IndexPatternSelectProps, StatefulSearchBarProps } from './ui'; import { UsageCollectionSetup } from '../../usage_collection/public'; import { Setup as InspectorSetup } from '../../inspector/public'; +import { NowProviderPublicContract } from './now_provider'; export interface DataPublicPluginEnhancements { search: SearchEnhancements; @@ -118,6 +119,8 @@ export interface DataPublicPluginStart { * {@link DataPublicPluginStartUi} */ ui: DataPublicPluginStartUi; + + nowProvider: NowProviderPublicContract; } export interface IDataPluginServices extends Partial { diff --git a/src/plugins/discover/public/application/angular/discover_state.ts b/src/plugins/discover/public/application/angular/discover_state.ts index f52bc8b49ba42..9bf3cc587a3d8 100644 --- a/src/plugins/discover/public/application/angular/discover_state.ts +++ b/src/plugins/discover/public/application/angular/discover_state.ts @@ -282,11 +282,14 @@ function createUrlGeneratorState({ appStateContainer, data, getSavedSearchId, - forceAbsoluteTime, // TODO: not implemented + forceAbsoluteTime, }: { appStateContainer: StateContainer; data: DataPublicPluginStart; getSavedSearchId: () => string | undefined; + /** + * Can force time range from time filter to convert from relative to absolute time range + */ forceAbsoluteTime: boolean; }): DiscoverUrlGeneratorState { const appState = appStateContainer.get(); @@ -295,7 +298,9 @@ function createUrlGeneratorState({ indexPatternId: appState.index, query: appState.query, savedSearchId: getSavedSearchId(), - timeRange: data.query.timefilter.timefilter.getTime(), // TODO: handle relative time range + timeRange: forceAbsoluteTime + ? data.query.timefilter.timefilter.getAbsoluteTime() + : data.query.timefilter.timefilter.getTime(), searchSessionId: data.search.session.getSessionId(), columns: appState.columns, sort: appState.sort, diff --git a/src/plugins/discover/public/application/embeddable/search_embeddable.ts b/src/plugins/discover/public/application/embeddable/search_embeddable.ts index e4a8ab7bc67ff..6919dc1bef286 100644 --- a/src/plugins/discover/public/application/embeddable/search_embeddable.ts +++ b/src/plugins/discover/public/application/embeddable/search_embeddable.ts @@ -29,7 +29,6 @@ import { Filter, TimeRange, FilterManager, - getTime, Query, IFieldType, } from '../../../../data/public'; @@ -98,7 +97,6 @@ export class SearchEmbeddable private panelTitle: string = ''; private filtersSearchSource?: ISearchSource; private searchInstance?: JQLite; - private autoRefreshFetchSubscription?: Subscription; private subscription?: Subscription; public readonly type = SEARCH_EMBEDDABLE_TYPE; private filterManager: FilterManager; @@ -148,10 +146,6 @@ export class SearchEmbeddable }; this.initializeSearchScope(); - this.autoRefreshFetchSubscription = this.services.timefilter - .getAutoRefreshFetch$() - .subscribe(this.fetch); - this.subscription = this.getUpdated$().subscribe(() => { this.panelTitle = this.output.title || ''; @@ -199,9 +193,7 @@ export class SearchEmbeddable if (this.subscription) { this.subscription.unsubscribe(); } - if (this.autoRefreshFetchSubscription) { - this.autoRefreshFetchSubscription.unsubscribe(); - } + if (this.abortController) this.abortController.abort(); } @@ -224,7 +216,7 @@ export class SearchEmbeddable const timeRangeSearchSource = searchSource.create(); timeRangeSearchSource.setField('filter', () => { if (!this.searchScope || !this.input.timeRange) return; - return getTime(indexPattern, this.input.timeRange); + return this.services.timefilter.createFilter(indexPattern, this.input.timeRange); }); this.filtersSearchSource = searchSource.create(); diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts index 3956f930758d7..590b65e1af13d 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts @@ -108,7 +108,6 @@ export class VisualizeEmbeddable private vis: Vis; private domNode: any; public readonly type = VISUALIZE_EMBEDDABLE_TYPE; - private autoRefreshFetchSubscription: Subscription; private abortController?: AbortController; private readonly deps: VisualizeEmbeddableFactoryDeps; private readonly inspectorAdapters?: Adapters; @@ -152,10 +151,6 @@ export class VisualizeEmbeddable this.attributeService = attributeService; this.savedVisualizationsLoader = savedVisualizationsLoader; - this.autoRefreshFetchSubscription = timefilter - .getAutoRefreshFetch$() - .subscribe(this.updateHandler.bind(this)); - this.subscriptions.push( this.getUpdated$().subscribe(() => { const isDirty = this.handleChanges(); @@ -368,7 +363,6 @@ export class VisualizeEmbeddable this.handler.destroy(); this.handler.getElement().remove(); } - this.autoRefreshFetchSubscription.unsubscribe(); } public reload = () => { diff --git a/src/plugins/visualize/public/application/components/visualize_top_nav.tsx b/src/plugins/visualize/public/application/components/visualize_top_nav.tsx index 627d5cd00147b..becabc60eff16 100644 --- a/src/plugins/visualize/public/application/components/visualize_top_nav.tsx +++ b/src/plugins/visualize/public/application/components/visualize_top_nav.tsx @@ -190,6 +190,17 @@ const TopNav = ({ } }, [vis.params, vis.type, services.data.indexPatterns, vis.data.indexPattern]); + useEffect(() => { + const autoRefreshFetchSub = services.data.query.timefilter.timefilter + .getAutoRefreshFetch$() + .subscribe(() => { + visInstance.embeddableHandler.reload(); + }); + return () => { + autoRefreshFetchSub.unsubscribe(); + }; + }, [services.data.query.timefilter.timefilter, visInstance.embeddableHandler]); + return isChromeVisible ? ( /** * Most visualizations have all search bar components enabled. diff --git a/test/functional/services/dashboard/panel_actions.ts b/test/functional/services/dashboard/panel_actions.ts index 7e5ef068e2184..8ae7a6b50c111 100644 --- a/test/functional/services/dashboard/panel_actions.ts +++ b/test/functional/services/dashboard/panel_actions.ts @@ -33,6 +33,7 @@ export function DashboardPanelActionsProvider({ getService, getPageObjects }: Ft const log = getService('log'); const testSubjects = getService('testSubjects'); const PageObjects = getPageObjects(['header', 'common']); + const inspector = getService('inspector'); return new (class DashboardPanelActions { async findContextMenu(parent?: WebElementWrapper) { @@ -163,6 +164,16 @@ export function DashboardPanelActionsProvider({ getService, getPageObjects }: Ft await this.openInspector(header); } + async getSearchSessionIdByTitle(title: string) { + await this.openInspectorByTitle(title); + await inspector.openInspectorRequestsView(); + const searchSessionId = await ( + await testSubjects.find('inspectorRequestSearchSessionId') + ).getAttribute('data-search-session-id'); + await inspector.close(); + return searchSessionId; + } + async openInspector(parent?: WebElementWrapper) { await this.openContextMenu(parent); const exists = await testSubjects.exists(OPEN_INSPECTOR_TEST_SUBJ); diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx index 04f747f42ac66..efa535d5bcf8a 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Subject } from 'rxjs'; import { Embeddable, LensByValueInput, @@ -13,13 +12,7 @@ import { LensEmbeddableInput, } from './embeddable'; import { ReactExpressionRendererProps } from 'src/plugins/expressions/public'; -import { - Query, - TimeRange, - Filter, - TimefilterContract, - IndexPatternsContract, -} from 'src/plugins/data/public'; +import { Query, TimeRange, Filter, IndexPatternsContract } from 'src/plugins/data/public'; import { Document } from '../../persistence'; import { dataPluginMock } from '../../../../../../src/plugins/data/public/mocks'; import { VIS_EVENT_TO_TRIGGER } from '../../../../../../src/plugins/visualizations/public/embeddable'; @@ -536,49 +529,4 @@ describe('embeddable', () => { expect(expressionRenderer).toHaveBeenCalledTimes(1); }); - - it('should re-render on auto refresh fetch observable', async () => { - const timeRange: TimeRange = { from: 'now-15d', to: 'now' }; - const query: Query = { language: 'kquery', query: '' }; - const filters: Filter[] = [{ meta: { alias: 'test', negate: false, disabled: true } }]; - - const autoRefreshFetchSubject = new Subject(); - const timefilter = ({ - getAutoRefreshFetch$: () => autoRefreshFetchSubject.asObservable(), - } as unknown) as TimefilterContract; - - const embeddable = new Embeddable( - { - timefilter, - attributeService, - expressionRenderer, - basePath, - indexPatternService: {} as IndexPatternsContract, - editable: true, - getTrigger, - documentToExpression: () => - Promise.resolve({ - type: 'expression', - chain: [ - { type: 'function', function: 'my', arguments: {} }, - { type: 'function', function: 'expression', arguments: {} }, - ], - }), - }, - { id: '123', timeRange, query, filters } as LensEmbeddableInput - ); - await embeddable.initializeSavedVis({ - id: '123', - timeRange, - query, - filters, - } as LensEmbeddableInput); - embeddable.render(mountpoint); - - act(() => { - autoRefreshFetchSubject.next(); - }); - - expect(expressionRenderer).toHaveBeenCalledTimes(2); - }); }); diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx index e2d637dd6684a..949d58c38037d 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx @@ -96,7 +96,6 @@ export class Embeddable private expression: string | undefined | null; private domNode: HTMLElement | Element | undefined; private subscription: Subscription; - private autoRefreshFetchSubscription: Subscription; private isInitialized = false; private activeData: Partial | undefined; @@ -127,10 +126,6 @@ export class Embeddable this.onContainerStateChanged(this.input) ); - this.autoRefreshFetchSubscription = deps.timefilter - .getAutoRefreshFetch$() - .subscribe(this.reload.bind(this)); - const input$ = this.getInput$(); // Lens embeddable does not re-render when embeddable input changes in @@ -450,6 +445,5 @@ export class Embeddable if (this.subscription) { this.subscription.unsubscribe(); } - this.autoRefreshFetchSubscription.unsubscribe(); } } diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/use_timefilter.ts b/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/use_timefilter.ts index 949de51cf2c2d..fce14c68bfd38 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/use_timefilter.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/use_timefilter.ts @@ -4,36 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { TimefilterContract } from '../../../../../../../../src/plugins/data/public'; -import { Observable } from 'rxjs'; +import { dataPluginMock } from '../../../../../../../../src/plugins/data/public/mocks'; -/** - * Copy from {@link '../../../../../../../../src/plugins/data/public/query/timefilter/timefilter_service.mock'} - */ -const timefilterMock: jest.Mocked = { - isAutoRefreshSelectorEnabled: jest.fn(), - isTimeRangeSelectorEnabled: jest.fn(), - isTimeTouched: jest.fn(), - getEnabledUpdated$: jest.fn(), - getTimeUpdate$: jest.fn(), - getRefreshIntervalUpdate$: jest.fn(), - getAutoRefreshFetch$: jest.fn(() => new Observable()), - getFetch$: jest.fn(), - getTime: jest.fn(), - setTime: jest.fn(), - setRefreshInterval: jest.fn(), - getRefreshInterval: jest.fn(), - getActiveBounds: jest.fn(), - disableAutoRefreshSelector: jest.fn(), - disableTimeRangeSelector: jest.fn(), - enableAutoRefreshSelector: jest.fn(), - enableTimeRangeSelector: jest.fn(), - getBounds: jest.fn(), - calculateBounds: jest.fn(), - createFilter: jest.fn(), - getRefreshIntervalDefaults: jest.fn(), - getTimeDefaults: jest.fn(), -}; +const timefilterMock = dataPluginMock.createStartContract().query.timefilter.timefilter; export const useTimefilter = jest.fn(() => { return timefilterMock; diff --git a/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/async_search.ts b/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/async_search.ts index 4859b2474f860..a1de22318ade4 100644 --- a/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/async_search.ts +++ b/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/async_search.ts @@ -6,17 +6,14 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../ftr_provider_context'; -import { getSearchSessionIdByPanelProvider } from './get_search_session_id_by_panel'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const es = getService('es'); const testSubjects = getService('testSubjects'); const log = getService('log'); const PageObjects = getPageObjects(['common', 'header', 'dashboard', 'visChart']); - const getSearchSessionIdByPanel = getSearchSessionIdByPanelProvider(getService); + const dashboardPanelActions = getService('dashboardPanelActions'); const queryBar = getService('queryBar'); - const browser = getService('browser'); - const sendToBackground = getService('sendToBackground'); describe('dashboard with async search', () => { before(async function () { @@ -63,74 +60,24 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // but only single error toast because searches are grouped expect((await testSubjects.findAll('searchTimeoutError')).length).to.be(1); - const panel1SessionId1 = await getSearchSessionIdByPanel('Sum of Bytes by Extension'); - const panel2SessionId1 = await getSearchSessionIdByPanel( + const panel1SessionId1 = await dashboardPanelActions.getSearchSessionIdByTitle( + 'Sum of Bytes by Extension' + ); + const panel2SessionId1 = await dashboardPanelActions.getSearchSessionIdByTitle( 'Sum of Bytes by Extension (Delayed 5s)' ); expect(panel1SessionId1).to.be(panel2SessionId1); await queryBar.clickQuerySubmitButton(); - const panel1SessionId2 = await getSearchSessionIdByPanel('Sum of Bytes by Extension'); - const panel2SessionId2 = await getSearchSessionIdByPanel( + const panel1SessionId2 = await dashboardPanelActions.getSearchSessionIdByTitle( + 'Sum of Bytes by Extension' + ); + const panel2SessionId2 = await dashboardPanelActions.getSearchSessionIdByTitle( 'Sum of Bytes by Extension (Delayed 5s)' ); expect(panel1SessionId2).to.be(panel2SessionId2); expect(panel1SessionId1).not.to.be(panel1SessionId2); }); - - describe('Send to background', () => { - before(async () => { - await PageObjects.common.navigateToApp('dashboard'); - }); - - it('Restore using non-existing sessionId errors out. Refresh starts a new session and completes.', async () => { - await PageObjects.dashboard.loadSavedDashboard('Not Delayed'); - const url = await browser.getCurrentUrl(); - const fakeSessionId = '__fake__'; - const savedSessionURL = `${url}&searchSessionId=${fakeSessionId}`; - await browser.get(savedSessionURL); - await PageObjects.header.waitUntilLoadingHasFinished(); - await sendToBackground.expectState('restored'); - await testSubjects.existOrFail('embeddableErrorLabel'); // expected that panel errors out because of non existing session - - const session1 = await getSearchSessionIdByPanel('Sum of Bytes by Extension'); - expect(session1).to.be(fakeSessionId); - - await sendToBackground.refresh(); - await PageObjects.header.waitUntilLoadingHasFinished(); - await sendToBackground.expectState('completed'); - await testSubjects.missingOrFail('embeddableErrorLabel'); - const session2 = await getSearchSessionIdByPanel('Sum of Bytes by Extension'); - expect(session2).not.to.be(fakeSessionId); - }); - - it('Saves and restores a session', async () => { - await PageObjects.dashboard.loadSavedDashboard('Not Delayed'); - await PageObjects.dashboard.waitForRenderComplete(); - await sendToBackground.expectState('completed'); - await sendToBackground.save(); - await sendToBackground.expectState('backgroundCompleted'); - const savedSessionId = await getSearchSessionIdByPanel('Sum of Bytes by Extension'); - - // load URL to restore a saved session - const url = await browser.getCurrentUrl(); - const savedSessionURL = `${url}&searchSessionId=${savedSessionId}`; - await browser.get(savedSessionURL); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.dashboard.waitForRenderComplete(); - - // Check that session is restored - await sendToBackground.expectState('restored'); - await testSubjects.missingOrFail('embeddableErrorLabel'); - const data = await PageObjects.visChart.getBarChartData('Sum of bytes'); - expect(data.length).to.be(5); - - // switching dashboard to edit mode (or any other non-fetch required) state change - // should leave session state untouched - await PageObjects.dashboard.switchToEditMode(); - await sendToBackground.expectState('restored'); - }); - }); }); } diff --git a/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/get_search_session_id_by_panel.ts b/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/get_search_session_id_by_panel.ts deleted file mode 100644 index 6de85ca5459db..0000000000000 --- a/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/get_search_session_id_by_panel.ts +++ /dev/null @@ -1,22 +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. - */ - -// HELPERS -export function getSearchSessionIdByPanelProvider(getService: any) { - const dashboardPanelActions = getService('dashboardPanelActions'); - const inspector = getService('inspector'); - const testSubjects = getService('testSubjects'); - - return async function getSearchSessionIdByPanel(panelTitle: string) { - await dashboardPanelActions.openInspectorByTitle(panelTitle); - await inspector.openInspectorRequestsView(); - const searchSessionId = await ( - await testSubjects.find('inspectorRequestSearchSessionId') - ).getAttribute('data-search-session-id'); - await inspector.close(); - return searchSessionId; - }; -} diff --git a/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/index.ts b/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/index.ts index 83085983fef05..7a14a97e57066 100644 --- a/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/index.ts +++ b/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/index.ts @@ -24,6 +24,8 @@ export default function ({ loadTestFile, getService }: FtrProviderContext) { }); loadTestFile(require.resolve('./async_search')); + loadTestFile(require.resolve('./send_to_background')); + loadTestFile(require.resolve('./send_to_background_relative_time')); loadTestFile(require.resolve('./sessions_in_space')); }); } diff --git a/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/send_to_background.ts b/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/send_to_background.ts new file mode 100644 index 0000000000000..2edaeb1918b25 --- /dev/null +++ b/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/send_to_background.ts @@ -0,0 +1,83 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const es = getService('es'); + const testSubjects = getService('testSubjects'); + const log = getService('log'); + const PageObjects = getPageObjects(['common', 'header', 'dashboard', 'visChart']); + const dashboardPanelActions = getService('dashboardPanelActions'); + const browser = getService('browser'); + const sendToBackground = getService('sendToBackground'); + + describe('send to background', () => { + before(async function () { + const { body } = await es.info(); + if (!body.version.number.includes('SNAPSHOT')) { + log.debug('Skipping because this build does not have the required shard_delay agg'); + this.skip(); + } + await PageObjects.common.navigateToApp('dashboard'); + }); + + it('Restore using non-existing sessionId errors out. Refresh starts a new session and completes.', async () => { + await PageObjects.dashboard.loadSavedDashboard('Not Delayed'); + const url = await browser.getCurrentUrl(); + const fakeSessionId = '__fake__'; + const savedSessionURL = `${url}&searchSessionId=${fakeSessionId}`; + await browser.get(savedSessionURL); + await PageObjects.header.waitUntilLoadingHasFinished(); + await sendToBackground.expectState('restored'); + await testSubjects.existOrFail('embeddableErrorLabel'); // expected that panel errors out because of non existing session + + const session1 = await dashboardPanelActions.getSearchSessionIdByTitle( + 'Sum of Bytes by Extension' + ); + expect(session1).to.be(fakeSessionId); + + await sendToBackground.refresh(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await sendToBackground.expectState('completed'); + await testSubjects.missingOrFail('embeddableErrorLabel'); + const session2 = await dashboardPanelActions.getSearchSessionIdByTitle( + 'Sum of Bytes by Extension' + ); + expect(session2).not.to.be(fakeSessionId); + }); + + it('Saves and restores a session', async () => { + await PageObjects.dashboard.loadSavedDashboard('Not Delayed'); + await PageObjects.dashboard.waitForRenderComplete(); + await sendToBackground.expectState('completed'); + await sendToBackground.save(); + await sendToBackground.expectState('backgroundCompleted'); + const savedSessionId = await dashboardPanelActions.getSearchSessionIdByTitle( + 'Sum of Bytes by Extension' + ); + + // load URL to restore a saved session + const url = await browser.getCurrentUrl(); + const savedSessionURL = `${url}&searchSessionId=${savedSessionId}`; + await browser.get(savedSessionURL); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.dashboard.waitForRenderComplete(); + + // Check that session is restored + await sendToBackground.expectState('restored'); + await testSubjects.missingOrFail('embeddableErrorLabel'); + const data = await PageObjects.visChart.getBarChartData('Sum of bytes'); + expect(data.length).to.be(5); + + // switching dashboard to edit mode (or any other non-fetch required) state change + // should leave session state untouched + await PageObjects.dashboard.switchToEditMode(); + await sendToBackground.expectState('restored'); + }); + }); +} diff --git a/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/send_to_background_relative_time.ts b/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/send_to_background_relative_time.ts new file mode 100644 index 0000000000000..2234ca3e3b034 --- /dev/null +++ b/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/send_to_background_relative_time.ts @@ -0,0 +1,119 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const testSubjects = getService('testSubjects'); + const log = getService('log'); + const retry = getService('retry'); + const PageObjects = getPageObjects([ + 'common', + 'header', + 'dashboard', + 'visChart', + 'home', + 'timePicker', + ]); + const dashboardPanelActions = getService('dashboardPanelActions'); + const inspector = getService('inspector'); + const pieChart = getService('pieChart'); + const find = getService('find'); + const dashboardExpect = getService('dashboardExpect'); + const queryBar = getService('queryBar'); + const browser = getService('browser'); + const sendToBackground = getService('sendToBackground'); + + describe('send to background with relative time', () => { + before(async () => { + await PageObjects.common.sleep(5000); // this part was copied from `x-pack/test/functional/apps/dashboard/_async_dashboard.ts` and this was sleep was needed because of flakiness + await PageObjects.common.navigateToUrl('home', '/tutorial_directory/sampleData', { + useActualUrl: true, + }); + await PageObjects.header.waitUntilLoadingHasFinished(); + // use sample data set because it has recent relative time range and bunch of different visualizations + await PageObjects.home.addSampleDataSet('flights'); + await retry.tryForTime(10000, async () => { + const isInstalled = await PageObjects.home.isSampleDataSetInstalled('flights'); + expect(isInstalled).to.be(true); + }); + await PageObjects.common.navigateToApp('dashboard'); + }); + + after(async () => { + await PageObjects.common.navigateToUrl('home', '/tutorial_directory/sampleData', { + useActualUrl: true, + }); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.home.removeSampleDataSet('flights'); + const isInstalled = await PageObjects.home.isSampleDataSetInstalled('flights'); + expect(isInstalled).to.be(false); + }); + + it('Saves and restores a session with relative time ranges', async () => { + await PageObjects.dashboard.loadSavedDashboard('[Flights] Global Flight Dashboard'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.timePicker.pauseAutoRefresh(); // sample data has auto-refresh on + await queryBar.submitQuery(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.dashboard.waitForRenderComplete(); + await checkSampleDashboardLoaded(); + + await sendToBackground.expectState('completed'); + await sendToBackground.save(); + await sendToBackground.expectState('backgroundCompleted'); + const savedSessionId = await dashboardPanelActions.getSearchSessionIdByTitle( + '[Flights] Airline Carrier' + ); + const resolvedTimeRange = await getResolvedTimeRangeFromPanel('[Flights] Airline Carrier'); + + // load URL to restore a saved session + const url = await browser.getCurrentUrl(); + const savedSessionURL = `${url}&searchSessionId=${savedSessionId}` + .replace('now-24h', `'${resolvedTimeRange.gte}'`) + .replace('now', `'${resolvedTimeRange.lte}'`); + log.debug('Trying to restore session by URL:', savedSessionId); + await browser.get(savedSessionURL); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.dashboard.waitForRenderComplete(); + await checkSampleDashboardLoaded(); + + // Check that session is restored + await sendToBackground.expectState('restored'); + }); + }); + + // HELPERS + + async function getResolvedTimeRangeFromPanel( + panelTitle: string + ): Promise<{ gte: string; lte: string }> { + await dashboardPanelActions.openInspectorByTitle(panelTitle); + await inspector.openInspectorRequestsView(); + await (await inspector.getOpenRequestDetailRequestButton()).click(); + const request = JSON.parse(await inspector.getCodeEditorValue()); + return request.query.bool.filter.find((f: any) => f.range).range.timestamp; + } + + async function checkSampleDashboardLoaded() { + log.debug('Checking no error labels'); + await testSubjects.missingOrFail('embeddableErrorLabel'); + log.debug('Checking pie charts rendered'); + await pieChart.expectPieSliceCount(4); + log.debug('Checking area, bar and heatmap charts rendered'); + await dashboardExpect.seriesElementCount(15); + log.debug('Checking saved searches rendered'); + await dashboardExpect.savedSearchRowCount(50); + log.debug('Checking input controls rendered'); + await dashboardExpect.inputControlItemCount(3); + log.debug('Checking tag cloud rendered'); + await dashboardExpect.tagCloudWithValuesFound(['Sunny', 'Rain', 'Clear', 'Cloudy', 'Hail']); + log.debug('Checking vega chart rendered'); + const tsvb = await find.existsByCssSelector('.vgaVis__view'); + expect(tsvb).to.be(true); + } +} diff --git a/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/sessions_in_space.ts b/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/sessions_in_space.ts index 97fba9e3aef91..7d00761b2fa9f 100644 --- a/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/sessions_in_space.ts +++ b/x-pack/test/send_search_to_background_integration/tests/apps/dashboard/async_search/sessions_in_space.ts @@ -5,7 +5,6 @@ */ import { FtrProviderContext } from '../../../../ftr_provider_context'; -import { getSearchSessionIdByPanelProvider } from './get_search_session_id_by_panel'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); @@ -19,7 +18,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'security', 'timePicker', ]); - const getSearchSessionIdByPanel = getSearchSessionIdByPanelProvider(getService); + const dashboardPanelActions = getService('dashboardPanelActions'); const browser = getService('browser'); const sendToBackground = getService('sendToBackground'); @@ -77,7 +76,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await sendToBackground.expectState('completed'); await sendToBackground.save(); await sendToBackground.expectState('backgroundCompleted'); - const savedSessionId = await getSearchSessionIdByPanel('A Pie in another space'); + const savedSessionId = await dashboardPanelActions.getSearchSessionIdByTitle( + 'A Pie in another space' + ); // load URL to restore a saved session const url = await browser.getCurrentUrl(); From 638b5e2a0848f7ea41a41a2e5f5b7943aa4007a0 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Tue, 12 Jan 2021 14:42:04 +0000 Subject: [PATCH 35/64] skip flaky suite (#87968) --- .../migrationsv2/integration_tests/migration.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/server/saved_objects/migrationsv2/integration_tests/migration.test.ts b/src/core/server/saved_objects/migrationsv2/integration_tests/migration.test.ts index 942021fd1918d..723f4c02db3ce 100644 --- a/src/core/server/saved_objects/migrationsv2/integration_tests/migration.test.ts +++ b/src/core/server/saved_objects/migrationsv2/integration_tests/migration.test.ts @@ -127,7 +127,8 @@ describe('migration v2', () => { await new Promise((resolve) => setTimeout(resolve, 10000)); }; - describe('migrating from 7.3.0-xpack version', () => { + // FLAKY: https://github.com/elastic/kibana/issues/87968 + describe.skip('migrating from 7.3.0-xpack version', () => { const migratedIndex = `.kibana_${kibanaVersion}_001`; beforeAll(async () => { From 3113d84c0f41d3eabe2258510d205766fa840368 Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Tue, 12 Jan 2021 08:48:31 -0600 Subject: [PATCH 36/64] Fix link in README (#87943) Was using an MD link but fixed it to use an asciidoc one. --- src/plugins/embeddable/README.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/embeddable/README.asciidoc b/src/plugins/embeddable/README.asciidoc index 5e3c5066f46c7..daa6040eab7eb 100644 --- a/src/plugins/embeddable/README.asciidoc +++ b/src/plugins/embeddable/README.asciidoc @@ -22,7 +22,7 @@ There is also an example of rendering dashboard container outside of dashboard a === Docs -(./docs/README.md)[Embeddable docs, guides & caveats] +link:./docs/README.md[Embeddable docs, guides & caveats] === API docs From 752a2bd943a8478ad5cd2fc6446f101cfadd2133 Mon Sep 17 00:00:00 2001 From: Bohdan Tsymbala Date: Tue, 12 Jan 2021 16:31:35 +0100 Subject: [PATCH 37/64] Extracted some parts of server side validation from schema into shared space. Changed the schema structure a bit to avoid casting inside validation code. (#87523) --- .../common/endpoint/schema/trusted_apps.ts | 88 ++++++++----------- .../endpoint/validation/trusted_apps.ts | 29 ++++++ 2 files changed, 67 insertions(+), 50 deletions(-) create mode 100644 x-pack/plugins/security_solution/common/endpoint/validation/trusted_apps.ts diff --git a/x-pack/plugins/security_solution/common/endpoint/schema/trusted_apps.ts b/x-pack/plugins/security_solution/common/endpoint/schema/trusted_apps.ts index 59c83242d4a9b..920109e8be7b5 100644 --- a/x-pack/plugins/security_solution/common/endpoint/schema/trusted_apps.ts +++ b/x-pack/plugins/security_solution/common/endpoint/schema/trusted_apps.ts @@ -6,13 +6,7 @@ import { schema, Type } from '@kbn/config-schema'; import { ConditionEntry, ConditionEntryField, OperatingSystem } from '../types'; - -const HASH_LENGTHS: readonly number[] = [ - 32, // MD5 - 40, // SHA1 - 64, // SHA256 -]; -const INVALID_CHARACTERS_PATTERN = /[^0-9a-f]/i; +import { getDuplicateFields, isValidHash } from '../validation/trusted_apps'; const entryFieldLabels: { [k in ConditionEntryField]: string } = { [ConditionEntryField.HASH]: 'Hash', @@ -20,9 +14,6 @@ const entryFieldLabels: { [k in ConditionEntryField]: string } = { [ConditionEntryField.SIGNER]: 'Signer', }; -const isValidHash = (value: string) => - HASH_LENGTHS.includes(value.length) && !INVALID_CHARACTERS_PATTERN.test(value); - export const DeleteTrustedAppsRequestSchema = { params: schema.object({ id: schema.string(), @@ -36,61 +27,58 @@ export const GetTrustedAppsRequestSchema = { }), }; -const createNewTrustedAppForOsScheme = ( +const ConditionEntryTypeSchema = schema.literal('match'); +const ConditionEntryOperatorSchema = schema.literal('included'); +const HashConditionEntrySchema = schema.object({ + field: schema.literal(ConditionEntryField.HASH), + type: ConditionEntryTypeSchema, + operator: ConditionEntryOperatorSchema, + value: schema.string({ + validate: (hash) => (isValidHash(hash) ? undefined : `Invalid hash value [${hash}]`), + }), +}); +const PathConditionEntrySchema = schema.object({ + field: schema.literal(ConditionEntryField.PATH), + type: ConditionEntryTypeSchema, + operator: ConditionEntryOperatorSchema, + value: schema.string({ minLength: 1 }), +}); +const SignerConditionEntrySchema = schema.object({ + field: schema.literal(ConditionEntryField.SIGNER), + type: ConditionEntryTypeSchema, + operator: ConditionEntryOperatorSchema, + value: schema.string({ minLength: 1 }), +}); + +const createNewTrustedAppForOsScheme = ( osSchema: Type, - fieldSchema: Type + entriesSchema: Type ) => schema.object({ name: schema.string({ minLength: 1, maxLength: 256 }), description: schema.maybe(schema.string({ minLength: 0, maxLength: 256, defaultValue: '' })), os: osSchema, - entries: schema.arrayOf( - schema.object({ - field: fieldSchema, - type: schema.literal('match'), - operator: schema.literal('included'), - value: schema.string({ minLength: 1 }), - }), - { - minSize: 1, - validate(entries) { - const usedFields = new Set(); - - for (const entry of entries) { - // unfortunately combination of generics and Type<...> for "field" causes type errors - const { field, value } = entry as ConditionEntry; - - if (usedFields.has(field)) { - return `[${entryFieldLabels[field]}] field can only be used once`; - } - - usedFields.add(field); - - if (field === ConditionEntryField.HASH && !isValidHash(value)) { - return `Invalid hash value [${value}]`; - } - } - }, - } - ), + entries: schema.arrayOf(entriesSchema, { + minSize: 1, + validate(entries) { + return ( + getDuplicateFields(entries) + .map((field) => `[${entryFieldLabels[field]}] field can only be used once`) + .join(', ') || undefined + ); + }, + }), }); export const PostTrustedAppCreateRequestSchema = { body: schema.oneOf([ createNewTrustedAppForOsScheme( schema.oneOf([schema.literal(OperatingSystem.LINUX), schema.literal(OperatingSystem.MAC)]), - schema.oneOf([ - schema.literal(ConditionEntryField.HASH), - schema.literal(ConditionEntryField.PATH), - ]) + schema.oneOf([HashConditionEntrySchema, PathConditionEntrySchema]) ), createNewTrustedAppForOsScheme( schema.literal(OperatingSystem.WINDOWS), - schema.oneOf([ - schema.literal(ConditionEntryField.HASH), - schema.literal(ConditionEntryField.PATH), - schema.literal(ConditionEntryField.SIGNER), - ]) + schema.oneOf([HashConditionEntrySchema, PathConditionEntrySchema, SignerConditionEntrySchema]) ), ]), }; diff --git a/x-pack/plugins/security_solution/common/endpoint/validation/trusted_apps.ts b/x-pack/plugins/security_solution/common/endpoint/validation/trusted_apps.ts new file mode 100644 index 0000000000000..55b2355249c22 --- /dev/null +++ b/x-pack/plugins/security_solution/common/endpoint/validation/trusted_apps.ts @@ -0,0 +1,29 @@ +/* + * 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 { ConditionEntry, ConditionEntryField } from '../types'; + +const HASH_LENGTHS: readonly number[] = [ + 32, // MD5 + 40, // SHA1 + 64, // SHA256 +]; +const INVALID_CHARACTERS_PATTERN = /[^0-9a-f]/i; + +export const isValidHash = (value: string) => + HASH_LENGTHS.includes(value.length) && !INVALID_CHARACTERS_PATTERN.test(value); + +export const getDuplicateFields = (entries: ConditionEntry[]) => { + const groupedFields = new Map(); + + entries.forEach((entry) => { + groupedFields.set(entry.field, [...(groupedFields.get(entry.field) || []), entry]); + }); + + return [...groupedFields.entries()] + .filter((entry) => entry[1].length > 1) + .map((entry) => entry[0]); +}; From 25bac193218d041bac14c3490d7f2d407ac20552 Mon Sep 17 00:00:00 2001 From: Davis Plumlee <56367316+dplumlee@users.noreply.github.com> Date: Tue, 12 Jan 2021 08:57:06 -0700 Subject: [PATCH 38/64] [Security Solution][Detection Rules] Fixes Threshold rule schema validator (#87946) --- .../rules/step_define_rule/schema.tsx | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/schema.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/schema.tsx index de2d390ee6784..79e9dcf71e68c 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/schema.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/schema.tsx @@ -13,7 +13,7 @@ import { singleEntryThreat, containsInvalidItems, } from '../../../../common/components/threat_match/helpers'; -import { isThreatMatchRule } from '../../../../../common/detection_engine/utils'; +import { isThreatMatchRule, isThresholdRule } from '../../../../../common/detection_engine/utils'; import { isMlRule } from '../../../../../common/machine_learning/helpers'; import { esKuery } from '../../../../../../../../src/plugins/data/public'; import { FieldValueQueryBar } from '../query_bar'; @@ -216,16 +216,25 @@ export const schema: FormSchema = { ), validations: [ { - validator: fieldValidators.numberGreaterThanField({ - than: 1, - message: i18n.translate( - 'xpack.securitySolution.detectionEngine.validations.thresholdValueFieldData.numberGreaterThanOrEqualOneErrorMessage', - { - defaultMessage: 'Value must be greater than or equal to one.', - } - ), - allowEquality: true, - }), + validator: ( + ...args: Parameters + ): ReturnType> | undefined => { + const [{ formData }] = args; + const needsValidation = isThresholdRule(formData.ruleType); + if (!needsValidation) { + return; + } + return fieldValidators.numberGreaterThanField({ + than: 1, + message: i18n.translate( + 'xpack.securitySolution.detectionEngine.validations.thresholdValueFieldData.numberGreaterThanOrEqualOneErrorMessage', + { + defaultMessage: 'Value must be greater than or equal to one.', + } + ), + allowEquality: true, + })(...args); + }, }, ], }, From 48efd29a537d193c5eb9d675c3bc4341c5eb7d3a Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Tue, 12 Jan 2021 07:57:55 -0800 Subject: [PATCH 39/64] Bump elastic-apm-node to v3.10.0 for @elastic/elasticsearch instrumentation (#87952) --- package.json | 2 +- yarn.lock | 39 ++++++++++++++++----------------------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index f8fe8d7c7bac4..8a3a8151f8910 100644 --- a/package.json +++ b/package.json @@ -195,7 +195,7 @@ "dedent": "^0.7.0", "deep-freeze-strict": "^1.1.1", "del": "^5.1.0", - "elastic-apm-node": "^3.7.0", + "elastic-apm-node": "^3.10.0", "elasticsearch": "^16.7.0", "execa": "^4.0.2", "exit-hook": "^2.2.0", diff --git a/yarn.lock b/yarn.lock index 9c27686f1e922..4c4a2f1ffc3dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12100,10 +12100,10 @@ ejs@^3.1.2, ejs@^3.1.5: dependencies: jake "^10.6.1" -elastic-apm-http-client@^9.4.0: - version "9.4.0" - resolved "https://registry.yarnpkg.com/elastic-apm-http-client/-/elastic-apm-http-client-9.4.0.tgz#1c985923369f0c511b94d5c20f6d13aef588cb55" - integrity sha512-/jOZDyfzLNwHrNkPAI+AspLg0TXYXODWT+I1eoAWRCB7gP1vKvzUQAsP5iChodVqCbAj1eUNXB0KrvM6b07Thw== +elastic-apm-http-client@^9.4.2: + version "9.4.2" + resolved "https://registry.yarnpkg.com/elastic-apm-http-client/-/elastic-apm-http-client-9.4.2.tgz#b479817b13ef38020991ccf1c9af9e335f92314a" + integrity sha512-zhOf0+cIO45tJgvQw3fWjXRWqO2MizCC9cvnQpMH2NNsQItXnZfJilhmiYJr8XYi50FxnlOvaav8koZ6tcObmw== dependencies: breadth-filter "^2.0.0" container-info "^1.0.1" @@ -12115,10 +12115,10 @@ elastic-apm-http-client@^9.4.0: stream-chopper "^3.0.1" unicode-byte-truncate "^1.0.0" -elastic-apm-node@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/elastic-apm-node/-/elastic-apm-node-3.7.0.tgz#168f0cfce8d93b5ebc82f387b158fa0924de9d7a" - integrity sha512-ZH3Xru6eLbUyfuNe+EnTOcKlm0B+MKduu1lCXXwEM8CDfDceW1Ks9FtmTaTeZHZW4nMacieGZMpxETrceoVk/A== +elastic-apm-node@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/elastic-apm-node/-/elastic-apm-node-3.10.0.tgz#2b061613a2fbeb3bba4e3b87040dab55df1d8583" + integrity sha512-H1DOrpr0CwX88awQqSM4UbHGdfsk7xJ4GM6R1uYuFk1zILX/eozylcm6dYSKirpXwwMLxGSRFTOCaMa8fqiLjQ== dependencies: after-all-results "^2.0.0" async-value-promise "^1.1.1" @@ -12126,9 +12126,10 @@ elastic-apm-node@^3.7.0: console-log-level "^1.4.1" cookie "^0.4.0" core-util-is "^1.0.2" - elastic-apm-http-client "^9.4.0" + elastic-apm-http-client "^9.4.2" end-of-stream "^1.4.4" error-stack-parser "^2.0.6" + escape-string-regexp "^4.0.0" fast-safe-stringify "^2.0.7" http-headers "^3.0.2" http-request-to-url "^1.0.0" @@ -12139,7 +12140,6 @@ elastic-apm-node@^3.7.0: object-identity-map "^1.0.2" original-url "^1.2.3" read-pkg-up "^7.0.1" - redact-secrets "^1.0.0" relative-microtime "^2.0.0" require-ancestors "^1.0.0" require-in-the-middle "^5.0.3" @@ -12149,6 +12149,7 @@ elastic-apm-node@^3.7.0: sql-summary "^1.0.1" stackman "^4.0.1" traceparent "^1.0.0" + traverse "^0.6.6" unicode-byte-truncate "^1.0.0" elasticsearch@^16.4.0, elasticsearch@^16.7.0: @@ -12639,6 +12640,11 @@ escape-string-regexp@2.0.0, escape-string-regexp@^2.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + escodegen@^1.11.0, escodegen@^1.11.1, escodegen@^1.12.0, escodegen@^1.14.1: version "1.14.3" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" @@ -16989,11 +16995,6 @@ is-root@2.1.0: resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== -is-secret@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-secret/-/is-secret-1.2.1.tgz#04b9ca1880ea763049606cfe6c2a08a93f33abe3" - integrity sha512-VtBantcgKL2a64fDeCmD1JlkHToh3v0bVOhyJZ5aGTjxtCgrdNcjaC9GaaRFXi19gA4/pYFpnuyoscIgQCFSMQ== - is-set@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43" @@ -23861,14 +23862,6 @@ recursive-readdir@2.2.2: dependencies: minimatch "3.0.4" -redact-secrets@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redact-secrets/-/redact-secrets-1.0.0.tgz#60f1db56924fe90a203ba8ccb39283cdbb0d907c" - integrity sha1-YPHbVpJP6QogO6jMs5KDzbsNkHw= - dependencies: - is-secret "^1.0.0" - traverse "^0.6.6" - redent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" From ef441cca24e15f6ea1100baa82b3fce34842c044 Mon Sep 17 00:00:00 2001 From: igoristic Date: Tue, 12 Jan 2021 11:06:48 -0500 Subject: [PATCH 40/64] Alerts Status on clusters listing page (#87969) --- .../monitoring/public/components/cluster/listing/listing.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/monitoring/public/components/cluster/listing/listing.js b/x-pack/plugins/monitoring/public/components/cluster/listing/listing.js index 6aa6321ba6081..89d69da0f5173 100644 --- a/x-pack/plugins/monitoring/public/components/cluster/listing/listing.js +++ b/x-pack/plugins/monitoring/public/components/cluster/listing/listing.js @@ -112,7 +112,7 @@ const getColumns = ( }, { name: i18n.translate('xpack.monitoring.cluster.listing.statusColumnTitle', { - defaultMessage: 'Status', + defaultMessage: 'Alerts Status', }), field: 'status', 'data-test-subj': 'alertsStatus', From 0b7e83f736f32720c5e5c7c61a4c72ff8314b23a Mon Sep 17 00:00:00 2001 From: Alexey Antonov Date: Tue, 12 Jan 2021 19:28:45 +0300 Subject: [PATCH 41/64] [TSVB] Allow custom label for fields via index pattern field management (#84612) * [TSVB] Allow custom label for fields via index pattern field management Closes: #84336 * replace saveObject, elasticsearch client to new one * fix CI * update schema * fix Top Hit * some changes * partially move getting fields into client side * fix PR comments * fix issue with getting fields * move SanitizedFieldType to common types * fix issue on changing index pattern * fix issue * fix regression * some work * remove extractFieldName, createCustomLabelSelectHandler * request/response processors should be async * some work * remove tests for createCustomLabelSelectHandler * fix table * fix placeholder * some work * fix jest * fix CI * fix label for table view * test: visualize app visual builder switch index patterns should be able to switch between index patterns * fix functional tests * fix sorting * fix labels for entire timerange mode * add createFieldsFetcher method * table view - fix pivot label * fix PR comments * fix issue with selecting buckets scripts * fix types * Update create_select_handler.test.ts * fix PR comments Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../__snapshots__/model_options.test.js.snap | 11 -- ...{agg_lookup.test.js => agg_lookup.test.ts} | 5 +- .../common/{agg_lookup.js => agg_lookup.ts} | 15 +- ..._label.test.js => calculate_label.test.ts} | 63 ++++---- ...{calculate_label.js => calculate_label.ts} | 28 +++- ...test.js => extract_index_patterns.test.ts} | 28 +--- ..._patterns.js => extract_index_patterns.ts} | 20 ++- .../common/{field_types.js => field_types.ts} | 14 +- .../{model_options.js => model_options.ts} | 14 +- ..._data_modes.js => timerange_data_modes.ts} | 8 +- ...tile_number.js => to_percentile_number.ts} | 2 +- .../vis_type_timeseries/common/types.ts | 9 +- .../vis_type_timeseries/common/vis_schema.ts | 23 +-- .../application/components/aggs/agg.tsx | 5 + .../components/aggs/calculation.js | 5 +- .../components/aggs/cumulative_sum.js | 5 +- .../application/components/aggs/derivative.js | 4 +- .../components/aggs/field_select.js | 115 --------------- .../components/aggs/field_select.tsx | 139 ++++++++++++++++++ .../components/aggs/filter_ratio.js | 1 + .../application/components/aggs/math.js | 5 +- .../components/aggs/metric_select.js | 30 ++-- .../components/aggs/moving_average.js | 4 +- .../aggs/percentile_rank/percentile_rank.tsx | 15 +- .../components/aggs/positive_only.js | 4 +- .../components/aggs/serial_diff.js | 4 +- .../application/components/aggs/std_agg.js | 2 + .../components/aggs/std_sibling.js | 4 +- .../application/components/aggs/vars.js | 3 + .../components/annotations_editor.js | 1 + .../application/components/index_pattern.js | 12 +- ....test.js => create_select_handler.test.ts} | 31 ++-- .../components/lib/create_select_handler.ts} | 14 +- .../components/lib/series_change_handler.js | 7 +- .../components/panel_config/markdown.js | 2 +- .../components/panel_config/table.js | 2 +- .../splits/__snapshots__/terms.test.js.snap | 21 ++- .../application/components/splits/terms.js | 1 + .../application/components/vis_editor.js | 41 ++++-- .../components/vis_types/table/vis.js | 22 +-- .../application/components/vis_with_splits.js | 8 +- .../public/application/editor_controller.js | 27 +--- .../lib/{fetch_fields.js => fetch_fields.ts} | 38 +++-- .../server/lib/get_fields.ts | 39 +++-- .../server/lib/get_vis_data.ts | 8 + .../search_strategy_registry.ts | 7 +- .../abstract_search_strategy.test.js | 12 +- .../strategies/abstract_search_strategy.ts | 53 +++++-- .../strategies/default_search_strategy.ts | 8 + .../annotations/build_request_body.js | 4 +- .../annotations/get_request_params.js | 8 +- .../server/lib/vis_data/get_series_data.js | 9 +- .../server/lib/vis_data/get_table_data.js | 33 ++++- .../lib/vis_data/helpers/bucket_transform.js | 3 +- .../lib/vis_data/helpers/fields_fetcher.ts} | 24 ++- .../server/lib/vis_data/helpers/get_splits.js | 11 +- .../lib/vis_data/helpers/get_splits.test.js | 46 ++++-- .../annotations/date_histogram.js | 8 +- .../request_processors/annotations/query.js | 7 +- .../annotations/top_hits.js | 1 + .../series/date_histogram.js | 12 +- .../series/date_histogram.test.js | 41 ++++-- .../series/filter_ratios.js | 3 +- .../series/metric_buckets.js | 7 +- .../series/metric_buckets.test.js | 10 +- .../series/positive_rate.js | 13 +- .../series/positive_rate.test.js | 12 +- .../series/sibling_buckets.js | 6 +- .../series/sibling_buckets.test.js | 10 +- .../series/split_by_terms.js | 17 ++- .../table/date_histogram.js | 10 +- .../request_processors/table/filter_ratios.js | 3 +- .../table/metric_buckets.js | 6 +- .../request_processors/table/pivot.js | 1 + .../request_processors/table/positive_rate.js | 6 +- .../table/sibling_buckets.js | 6 +- .../response_processors/series/math.js | 6 +- .../response_processors/series/math.test.js | 53 +++++-- .../response_processors/series/percentile.js | 6 +- .../series/percentile.test.js | 11 +- .../series/percentile_rank.js | 6 +- .../response_processors/series/series_agg.js | 11 +- .../series/series_agg.test.js | 11 +- .../series/std_deviation_bands.js | 56 +++---- .../series/std_deviation_bands.test.js | 8 +- .../series/std_deviation_sibling.js | 6 +- .../series/std_deviation_sibling.test.js | 8 +- .../response_processors/series/std_metric.js | 9 +- .../series/std_metric.test.js | 22 ++- .../response_processors/series/std_sibling.js | 7 +- .../series/std_sibling.test.js | 12 +- .../series/time_shift.test.js | 12 +- .../response_processors/table/index.js | 1 - .../response_processors/table/percentile.js | 7 +- .../table/percentile_rank.js | 8 +- .../response_processors/table/series_agg.js | 11 +- .../response_processors/table/std_metric.js | 6 +- .../response_processors/table/std_sibling.js | 6 +- .../series/build_request_body.test.ts | 8 +- .../lib/vis_data/series/build_request_body.ts | 4 +- .../lib/vis_data/series/get_request_params.js | 8 +- .../vis_data/series/handle_response_body.js | 12 +- .../lib/vis_data/table/build_request_body.js | 4 +- .../lib/vis_data/table/process_bucket.js | 53 ++++--- .../lib/vis_data/table/process_bucket.test.js | 19 ++- .../page_objects/visual_builder_page.ts | 3 + .../rollup_search_strategy.test.ts | 7 +- .../rollup_search_strategy.ts | 22 +-- 108 files changed, 980 insertions(+), 699 deletions(-) delete mode 100644 src/plugins/vis_type_timeseries/common/__snapshots__/model_options.test.js.snap rename src/plugins/vis_type_timeseries/common/{agg_lookup.test.js => agg_lookup.test.ts} (83%) rename src/plugins/vis_type_timeseries/common/{agg_lookup.js => agg_lookup.ts} (92%) rename src/plugins/vis_type_timeseries/common/{calculate_label.test.js => calculate_label.test.ts} (56%) rename src/plugins/vis_type_timeseries/common/{calculate_label.js => calculate_label.ts} (84%) rename src/plugins/vis_type_timeseries/common/{extract_index_patterns.test.js => extract_index_patterns.test.ts} (73%) rename src/plugins/vis_type_timeseries/common/{extract_index_patterns.js => extract_index_patterns.ts} (73%) rename src/plugins/vis_type_timeseries/common/{field_types.js => field_types.ts} (85%) rename src/plugins/vis_type_timeseries/common/{model_options.js => model_options.ts} (79%) rename src/plugins/vis_type_timeseries/common/{timerange_data_modes.js => timerange_data_modes.ts} (91%) rename src/plugins/vis_type_timeseries/common/{to_percentile_number.js => to_percentile_number.ts} (94%) delete mode 100644 src/plugins/vis_type_timeseries/public/application/components/aggs/field_select.js create mode 100644 src/plugins/vis_type_timeseries/public/application/components/aggs/field_select.tsx rename src/plugins/vis_type_timeseries/public/application/components/lib/{create_select_handler.test.js => create_select_handler.test.ts} (56%) rename src/plugins/vis_type_timeseries/{common/model_options.test.js => public/application/components/lib/create_select_handler.ts} (71%) rename src/plugins/vis_type_timeseries/public/application/lib/{fetch_fields.js => fetch_fields.ts} (64%) rename src/plugins/vis_type_timeseries/{public/application/components/lib/create_select_handler.js => server/lib/vis_data/helpers/fields_fetcher.ts} (59%) diff --git a/src/plugins/vis_type_timeseries/common/__snapshots__/model_options.test.js.snap b/src/plugins/vis_type_timeseries/common/__snapshots__/model_options.test.js.snap deleted file mode 100644 index 0fca2a017b911..0000000000000 --- a/src/plugins/vis_type_timeseries/common/__snapshots__/model_options.test.js.snap +++ /dev/null @@ -1,11 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`src/legacy/core_plugins/metrics/common/model_options.js MODEL_TYPES should match a snapshot of constants 1`] = ` -Object { - "UNWEIGHTED": "simple", - "WEIGHTED_EXPONENTIAL": "ewma", - "WEIGHTED_EXPONENTIAL_DOUBLE": "holt", - "WEIGHTED_EXPONENTIAL_TRIPLE": "holt_winters", - "WEIGHTED_LINEAR": "linear", -} -`; diff --git a/src/plugins/vis_type_timeseries/common/agg_lookup.test.js b/src/plugins/vis_type_timeseries/common/agg_lookup.test.ts similarity index 83% rename from src/plugins/vis_type_timeseries/common/agg_lookup.test.js rename to src/plugins/vis_type_timeseries/common/agg_lookup.test.ts index a7c5d362e669c..d61cab6229305 100644 --- a/src/plugins/vis_type_timeseries/common/agg_lookup.test.js +++ b/src/plugins/vis_type_timeseries/common/agg_lookup.test.ts @@ -18,14 +18,15 @@ */ import { isBasicAgg } from './agg_lookup'; +import { MetricsItemsSchema } from './types'; describe('aggLookup', () => { describe('isBasicAgg(metric)', () => { test('returns true for a basic metric (count)', () => { - expect(isBasicAgg({ type: 'count' })).toEqual(true); + expect(isBasicAgg({ type: 'count' } as MetricsItemsSchema)).toEqual(true); }); test('returns false for a pipeline metric (derivative)', () => { - expect(isBasicAgg({ type: 'derivative' })).toEqual(false); + expect(isBasicAgg({ type: 'derivative' } as MetricsItemsSchema)).toEqual(false); }); }); }); diff --git a/src/plugins/vis_type_timeseries/common/agg_lookup.js b/src/plugins/vis_type_timeseries/common/agg_lookup.ts similarity index 92% rename from src/plugins/vis_type_timeseries/common/agg_lookup.js rename to src/plugins/vis_type_timeseries/common/agg_lookup.ts index 0a71ab34082f8..7cdae3f55978a 100644 --- a/src/plugins/vis_type_timeseries/common/agg_lookup.js +++ b/src/plugins/vis_type_timeseries/common/agg_lookup.ts @@ -17,10 +17,11 @@ * under the License. */ -import _ from 'lodash'; +import { omit, pick, includes } from 'lodash'; import { i18n } from '@kbn/i18n'; +import { MetricsItemsSchema } from './types'; -export const lookup = { +export const lookup: Record = { count: i18n.translate('visTypeTimeseries.aggLookup.countLabel', { defaultMessage: 'Count' }), calculation: i18n.translate('visTypeTimeseries.aggLookup.calculationLabel', { defaultMessage: 'Calculation', @@ -122,11 +123,11 @@ const pipeline = [ const byType = { _all: lookup, - pipeline: pipeline, - basic: _.omit(lookup, pipeline), - metrics: _.pick(lookup, ['count', 'avg', 'min', 'max', 'sum', 'cardinality', 'value_count']), + pipeline, + basic: omit(lookup, pipeline), + metrics: pick(lookup, ['count', 'avg', 'min', 'max', 'sum', 'cardinality', 'value_count']), }; -export function isBasicAgg(item) { - return _.includes(Object.keys(byType.basic), item.type); +export function isBasicAgg(item: MetricsItemsSchema) { + return includes(Object.keys(byType.basic), item.type); } diff --git a/src/plugins/vis_type_timeseries/common/calculate_label.test.js b/src/plugins/vis_type_timeseries/common/calculate_label.test.ts similarity index 56% rename from src/plugins/vis_type_timeseries/common/calculate_label.test.js rename to src/plugins/vis_type_timeseries/common/calculate_label.test.ts index a5af6d114c894..0f201d405ee0d 100644 --- a/src/plugins/vis_type_timeseries/common/calculate_label.test.js +++ b/src/plugins/vis_type_timeseries/common/calculate_label.test.ts @@ -18,66 +18,79 @@ */ import { calculateLabel } from './calculate_label'; +import type { MetricsItemsSchema } from './types'; describe('calculateLabel(metric, metrics)', () => { - test('returns "Unknown" for empty metric', () => { - expect(calculateLabel()).toEqual('Unknown'); - }); - test('returns the metric.alias if set', () => { - expect(calculateLabel({ alias: 'Example' })).toEqual('Example'); + expect(calculateLabel({ alias: 'Example' } as MetricsItemsSchema)).toEqual('Example'); }); test('returns "Count" for a count metric', () => { - expect(calculateLabel({ type: 'count' })).toEqual('Count'); + expect(calculateLabel({ type: 'count' } as MetricsItemsSchema)).toEqual('Count'); }); test('returns "Calculation" for a bucket script metric', () => { - expect(calculateLabel({ type: 'calculation' })).toEqual('Bucket Script'); + expect(calculateLabel({ type: 'calculation' } as MetricsItemsSchema)).toEqual('Bucket Script'); }); - test('returns formated label for series_agg', () => { - const label = calculateLabel({ type: 'series_agg', function: 'max' }); + test('returns formatted label for series_agg', () => { + const label = calculateLabel({ type: 'series_agg', function: 'max' } as MetricsItemsSchema); + expect(label).toEqual('Series Agg (max)'); }); - test('returns formated label for basic aggs', () => { - const label = calculateLabel({ type: 'avg', field: 'memory' }); + test('returns formatted label for basic aggs', () => { + const label = calculateLabel({ type: 'avg', field: 'memory' } as MetricsItemsSchema); + expect(label).toEqual('Average of memory'); }); - test('returns formated label for pipeline aggs', () => { - const metric = { id: 2, type: 'derivative', field: 1 }; - const metrics = [{ id: 1, type: 'max', field: 'network.out.bytes' }, metric]; + test('returns formatted label for pipeline aggs', () => { + const metric = ({ id: 2, type: 'derivative', field: 1 } as unknown) as MetricsItemsSchema; + const metrics = ([ + { id: 1, type: 'max', field: 'network.out.bytes' }, + metric, + ] as unknown) as MetricsItemsSchema[]; const label = calculateLabel(metric, metrics); + expect(label).toEqual('Derivative of Max of network.out.bytes'); }); - test('returns formated label for derivative of percentile', () => { - const metric = { id: 2, type: 'derivative', field: '1[50.0]' }; - const metrics = [{ id: 1, type: 'percentile', field: 'network.out.bytes' }, metric]; + test('returns formatted label for derivative of percentile', () => { + const metric = ({ + id: 2, + type: 'derivative', + field: '1[50.0]', + } as unknown) as MetricsItemsSchema; + const metrics = ([ + { id: 1, type: 'percentile', field: 'network.out.bytes' }, + metric, + ] as unknown) as MetricsItemsSchema[]; const label = calculateLabel(metric, metrics); + expect(label).toEqual('Derivative of Percentile of network.out.bytes (50.0)'); }); - test('returns formated label for pipeline aggs (deep)', () => { - const metric = { id: 3, type: 'derivative', field: 2 }; - const metrics = [ + test('returns formatted label for pipeline aggs (deep)', () => { + const metric = ({ id: 3, type: 'derivative', field: 2 } as unknown) as MetricsItemsSchema; + const metrics = ([ { id: 1, type: 'max', field: 'network.out.bytes' }, { id: 2, type: 'moving_average', field: 1 }, metric, - ]; + ] as unknown) as MetricsItemsSchema[]; const label = calculateLabel(metric, metrics); + expect(label).toEqual('Derivative of Moving Average of Max of network.out.bytes'); }); - test('returns formated label for pipeline aggs uses alias for field metric', () => { - const metric = { id: 2, type: 'derivative', field: 1 }; - const metrics = [ + test('returns formatted label for pipeline aggs uses alias for field metric', () => { + const metric = ({ id: 2, type: 'derivative', field: 1 } as unknown) as MetricsItemsSchema; + const metrics = ([ { id: 1, type: 'max', field: 'network.out.bytes', alias: 'Outbound Traffic' }, metric, - ]; + ] as unknown) as MetricsItemsSchema[]; const label = calculateLabel(metric, metrics); + expect(label).toEqual('Derivative of Outbound Traffic'); }); }); diff --git a/src/plugins/vis_type_timeseries/common/calculate_label.js b/src/plugins/vis_type_timeseries/common/calculate_label.ts similarity index 84% rename from src/plugins/vis_type_timeseries/common/calculate_label.js rename to src/plugins/vis_type_timeseries/common/calculate_label.ts index 96e9fa0825b25..33a1fbe6879ae 100644 --- a/src/plugins/vis_type_timeseries/common/calculate_label.js +++ b/src/plugins/vis_type_timeseries/common/calculate_label.ts @@ -18,8 +18,9 @@ */ import { includes, startsWith } from 'lodash'; -import { lookup } from './agg_lookup'; import { i18n } from '@kbn/i18n'; +import { lookup } from './agg_lookup'; +import { MetricsItemsSchema, SanitizedFieldType } from './types'; const paths = [ 'cumulative_sum', @@ -36,7 +37,15 @@ const paths = [ 'positive_only', ]; -export function calculateLabel(metric, metrics) { +export const extractFieldLabel = (fields: SanitizedFieldType[], name: string) => { + return fields.find((f) => f.name === name)?.label ?? name; +}; + +export const calculateLabel = ( + metric: MetricsItemsSchema, + metrics: MetricsItemsSchema[] = [], + fields: SanitizedFieldType[] = [] +): string => { if (!metric) { return i18n.translate('visTypeTimeseries.calculateLabel.unknownLabel', { defaultMessage: 'Unknown', @@ -73,7 +82,7 @@ export function calculateLabel(metric, metrics) { if (metric.type === 'positive_rate') { return i18n.translate('visTypeTimeseries.calculateLabel.positiveRateLabel', { defaultMessage: 'Counter Rate of {field}', - values: { field: metric.field }, + values: { field: extractFieldLabel(fields, metric.field!) }, }); } if (metric.type === 'static') { @@ -84,15 +93,15 @@ export function calculateLabel(metric, metrics) { } if (includes(paths, metric.type)) { - const targetMetric = metrics.find((m) => startsWith(metric.field, m.id)); - const targetLabel = calculateLabel(targetMetric, metrics); + const targetMetric = metrics.find((m) => startsWith(metric.field!, m.id)); + const targetLabel = calculateLabel(targetMetric!, metrics, fields); // For percentiles we need to parse the field id to extract the percentile // the user configured in the percentile aggregation and specified in the // submetric they selected. This applies only to pipeline aggs. if (targetMetric && targetMetric.type === 'percentile') { const percentileValueMatch = /\[([0-9\.]+)\]$/; - const matches = metric.field.match(percentileValueMatch); + const matches = metric.field!.match(percentileValueMatch); if (matches) { return i18n.translate( 'visTypeTimeseries.calculateLabel.lookupMetricTypeOfTargetWithAdditionalLabel', @@ -115,6 +124,9 @@ export function calculateLabel(metric, metrics) { return i18n.translate('visTypeTimeseries.calculateLabel.lookupMetricTypeOfMetricFieldRankLabel', { defaultMessage: '{lookupMetricType} of {metricField}', - values: { lookupMetricType: lookup[metric.type], metricField: metric.field }, + values: { + lookupMetricType: lookup[metric.type], + metricField: extractFieldLabel(fields, metric.field!), + }, }); -} +}; diff --git a/src/plugins/vis_type_timeseries/common/extract_index_patterns.test.js b/src/plugins/vis_type_timeseries/common/extract_index_patterns.test.ts similarity index 73% rename from src/plugins/vis_type_timeseries/common/extract_index_patterns.test.js rename to src/plugins/vis_type_timeseries/common/extract_index_patterns.test.ts index 385c0b58d12fd..69cbd9c3fe0b6 100644 --- a/src/plugins/vis_type_timeseries/common/extract_index_patterns.test.js +++ b/src/plugins/vis_type_timeseries/common/extract_index_patterns.test.ts @@ -18,16 +18,13 @@ */ import { extractIndexPatterns } from './extract_index_patterns'; +import { PanelSchema } from './types'; describe('extractIndexPatterns(vis)', () => { - let visParams; - let visFields; + let panel: PanelSchema; beforeEach(() => { - visFields = { - '*': [], - }; - visParams = { + panel = { index_pattern: '*', series: [ { @@ -40,25 +37,10 @@ describe('extractIndexPatterns(vis)', () => { }, ], annotations: [{ index_pattern: 'notes-*' }, { index_pattern: 'example-1-*' }], - }; + } as PanelSchema; }); test('should return index patterns', () => { - visFields = {}; - - expect(extractIndexPatterns(visParams, visFields)).toEqual([ - '*', - 'example-1-*', - 'example-2-*', - 'notes-*', - ]); - }); - - test('should return index patterns that do not exist in visFields', () => { - expect(extractIndexPatterns(visParams, visFields)).toEqual([ - 'example-1-*', - 'example-2-*', - 'notes-*', - ]); + expect(extractIndexPatterns(panel, '')).toEqual(['*', 'example-1-*', 'example-2-*', 'notes-*']); }); }); diff --git a/src/plugins/vis_type_timeseries/common/extract_index_patterns.js b/src/plugins/vis_type_timeseries/common/extract_index_patterns.ts similarity index 73% rename from src/plugins/vis_type_timeseries/common/extract_index_patterns.js rename to src/plugins/vis_type_timeseries/common/extract_index_patterns.ts index 3fb005b477199..ba30f6da02321 100644 --- a/src/plugins/vis_type_timeseries/common/extract_index_patterns.js +++ b/src/plugins/vis_type_timeseries/common/extract_index_patterns.ts @@ -17,17 +17,21 @@ * under the License. */ import { uniq } from 'lodash'; +import { PanelSchema } from '../common/types'; -export function extractIndexPatterns(panel, excludedFields = {}) { - const patterns = []; +export function extractIndexPatterns( + panel: PanelSchema, + defaultIndex?: PanelSchema['default_index_pattern'] +) { + const patterns: string[] = []; - if (!excludedFields[panel.index_pattern]) { + if (panel.index_pattern) { patterns.push(panel.index_pattern); } panel.series.forEach((series) => { const indexPattern = series.series_index_pattern; - if (indexPattern && series.override_index_pattern && !excludedFields[indexPattern]) { + if (indexPattern && series.override_index_pattern) { patterns.push(indexPattern); } }); @@ -35,15 +39,15 @@ export function extractIndexPatterns(panel, excludedFields = {}) { if (panel.annotations) { panel.annotations.forEach((item) => { const indexPattern = item.index_pattern; - if (indexPattern && !excludedFields[indexPattern]) { + if (indexPattern) { patterns.push(indexPattern); } }); } - if (patterns.length === 0) { - patterns.push(''); + if (patterns.length === 0 && defaultIndex) { + patterns.push(defaultIndex); } - return uniq(patterns).sort(); + return uniq(patterns).sort(); } diff --git a/src/plugins/vis_type_timeseries/common/field_types.js b/src/plugins/vis_type_timeseries/common/field_types.ts similarity index 85% rename from src/plugins/vis_type_timeseries/common/field_types.js rename to src/plugins/vis_type_timeseries/common/field_types.ts index f5323f1542a31..d12d4fe831659 100644 --- a/src/plugins/vis_type_timeseries/common/field_types.js +++ b/src/plugins/vis_type_timeseries/common/field_types.ts @@ -17,10 +17,10 @@ * under the License. */ -export const FIELD_TYPES = { - BOOLEAN: 'boolean', - DATE: 'date', - GEO: 'geo_point', - NUMBER: 'number', - STRING: 'string', -}; +export enum FIELD_TYPES { + BOOLEAN = 'boolean', + DATE = 'date', + GEO = 'geo_point', + NUMBER = 'number', + STRING = 'string', +} diff --git a/src/plugins/vis_type_timeseries/common/model_options.js b/src/plugins/vis_type_timeseries/common/model_options.ts similarity index 79% rename from src/plugins/vis_type_timeseries/common/model_options.js rename to src/plugins/vis_type_timeseries/common/model_options.ts index 22fe7a0abc842..1eefc92e7615a 100644 --- a/src/plugins/vis_type_timeseries/common/model_options.js +++ b/src/plugins/vis_type_timeseries/common/model_options.ts @@ -17,10 +17,10 @@ * under the License. */ -export const MODEL_TYPES = { - UNWEIGHTED: 'simple', - WEIGHTED_EXPONENTIAL: 'ewma', - WEIGHTED_EXPONENTIAL_DOUBLE: 'holt', - WEIGHTED_EXPONENTIAL_TRIPLE: 'holt_winters', - WEIGHTED_LINEAR: 'linear', -}; +export enum MODEL_TYPES { + UNWEIGHTED = 'simple', + WEIGHTED_EXPONENTIAL = 'ewma', + WEIGHTED_EXPONENTIAL_DOUBLE = 'holt', + WEIGHTED_EXPONENTIAL_TRIPLE = 'holt_winters', + WEIGHTED_LINEAR = 'linear', +} diff --git a/src/plugins/vis_type_timeseries/common/timerange_data_modes.js b/src/plugins/vis_type_timeseries/common/timerange_data_modes.ts similarity index 91% rename from src/plugins/vis_type_timeseries/common/timerange_data_modes.js rename to src/plugins/vis_type_timeseries/common/timerange_data_modes.ts index 7d69d36f213b7..7c8755baf3164 100644 --- a/src/plugins/vis_type_timeseries/common/timerange_data_modes.js +++ b/src/plugins/vis_type_timeseries/common/timerange_data_modes.ts @@ -22,19 +22,19 @@ * @constant * @public */ -export const TIME_RANGE_DATA_MODES = { +export enum TIME_RANGE_DATA_MODES { /** * Entire timerange mode will match all the documents selected in the * timerange timepicker */ - ENTIRE_TIME_RANGE: 'entire_time_range', + ENTIRE_TIME_RANGE = 'entire_time_range', /** * Last value mode will match only the documents for the specified interval * from the end of the timerange. */ - LAST_VALUE: 'last_value', -}; + LAST_VALUE = 'last_value', +} /** * Key for getting the Time Range mode from the Panel configuration object. diff --git a/src/plugins/vis_type_timeseries/common/to_percentile_number.js b/src/plugins/vis_type_timeseries/common/to_percentile_number.ts similarity index 94% rename from src/plugins/vis_type_timeseries/common/to_percentile_number.js rename to src/plugins/vis_type_timeseries/common/to_percentile_number.ts index b81133db8f084..51d60b99089eb 100644 --- a/src/plugins/vis_type_timeseries/common/to_percentile_number.js +++ b/src/plugins/vis_type_timeseries/common/to_percentile_number.ts @@ -18,5 +18,5 @@ */ const percentileNumberTest = /\d+\.\d+/; -export const toPercentileNumber = (value) => +export const toPercentileNumber = (value: string) => percentileNumberTest.test(`${value}`) ? value : `${value}.0`; diff --git a/src/plugins/vis_type_timeseries/common/types.ts b/src/plugins/vis_type_timeseries/common/types.ts index f8e1b740fc646..754a338811df9 100644 --- a/src/plugins/vis_type_timeseries/common/types.ts +++ b/src/plugins/vis_type_timeseries/common/types.ts @@ -18,7 +18,7 @@ */ import { TypeOf } from '@kbn/config-schema'; -import { metricsItems, panel, seriesItems, visPayloadSchema } from './vis_schema'; +import { metricsItems, panel, seriesItems, visPayloadSchema, fieldObject } from './vis_schema'; import { PANEL_TYPES } from './panel_types'; import { TimeseriesUIRestrictions } from './ui_restrictions'; @@ -26,6 +26,7 @@ export type SeriesItemsSchema = TypeOf; export type MetricsItemsSchema = TypeOf; export type PanelSchema = TypeOf; export type VisPayload = TypeOf; +export type FieldObject = TypeOf; interface PanelData { id: string; @@ -53,3 +54,9 @@ export type TimeseriesVisData = SeriesData & { */ series?: unknown[]; }; + +export interface SanitizedFieldType { + name: string; + type: string; + label?: string; +} diff --git a/src/plugins/vis_type_timeseries/common/vis_schema.ts b/src/plugins/vis_type_timeseries/common/vis_schema.ts index a90fa752ad7dc..40198ab98026e 100644 --- a/src/plugins/vis_type_timeseries/common/vis_schema.ts +++ b/src/plugins/vis_type_timeseries/common/vis_schema.ts @@ -47,6 +47,8 @@ const numberOptionalOrEmptyString = schema.maybe( schema.oneOf([numberOptional, schema.literal('')]) ); +export const fieldObject = stringOptionalNullable; + const annotationsItems = schema.object({ color: stringOptionalNullable, fields: stringOptionalNullable, @@ -58,7 +60,7 @@ const annotationsItems = schema.object({ index_pattern: stringOptionalNullable, query_string: schema.maybe(queryObject), template: stringOptionalNullable, - time_field: stringOptionalNullable, + time_field: fieldObject, }); const backgroundColorRulesItems = schema.object({ @@ -77,8 +79,9 @@ const gaugeColorRulesItems = schema.object({ value: schema.maybe(schema.nullable(schema.number())), }); export const metricsItems = schema.object({ - field: stringOptionalNullable, + field: fieldObject, id: stringRequired, + alias: stringOptionalNullable, metric_agg: stringOptionalNullable, numerator: schema.maybe(queryObject), denominator: schema.maybe(queryObject), @@ -98,7 +101,7 @@ export const metricsItems = schema.object({ variables: schema.maybe( schema.arrayOf( schema.object({ - field: stringOptionalNullable, + field: fieldObject, id: stringRequired, name: stringOptionalNullable, }) @@ -109,7 +112,7 @@ export const metricsItems = schema.object({ schema.arrayOf( schema.object({ id: stringRequired, - field: stringOptionalNullable, + field: fieldObject, mode: schema.oneOf([schema.literal('line'), schema.literal('band')]), shade: schema.oneOf([numberOptional, stringOptionalNullable]), value: schema.maybe(schema.oneOf([numberOptional, stringOptionalNullable])), @@ -123,7 +126,7 @@ export const metricsItems = schema.object({ size: stringOrNumberOptionalNullable, agg_with: stringOptionalNullable, order: stringOptionalNullable, - order_by: stringOptionalNullable, + order_by: fieldObject, }); const splitFiltersItems = schema.object({ @@ -134,7 +137,7 @@ const splitFiltersItems = schema.object({ }); export const seriesItems = schema.object({ - aggregate_by: stringOptionalNullable, + aggregate_by: fieldObject, aggregate_function: stringOptionalNullable, axis_position: stringRequired, axis_max: stringOrNumberOptionalNullable, @@ -176,7 +179,7 @@ export const seriesItems = schema.object({ seperate_axis: numberIntegerOptional, series_index_pattern: stringOptionalNullable, series_max_bars: numberIntegerOptional, - series_time_field: stringOptionalNullable, + series_time_field: fieldObject, series_interval: stringOptionalNullable, series_drop_last_bucket: numberIntegerOptional, split_color_mode: stringOptionalNullable, @@ -184,7 +187,7 @@ export const seriesItems = schema.object({ split_mode: stringRequired, stacked: stringRequired, steps: numberIntegerOptional, - terms_field: stringOptionalNullable, + terms_field: fieldObject, terms_order_by: stringOptionalNullable, terms_size: stringOptionalNullable, terms_direction: stringOptionalNullable, @@ -241,7 +244,7 @@ export const panel = schema.object({ markdown_vertical_align: stringOptionalNullable, markdown_less: stringOptionalNullable, markdown_css: stringOptionalNullable, - pivot_id: stringOptionalNullable, + pivot_id: fieldObject, pivot_label: stringOptionalNullable, pivot_type: stringOptionalNullable, pivot_rows: stringOptionalNullable, @@ -251,7 +254,7 @@ export const panel = schema.object({ tooltip_mode: schema.maybe( schema.oneOf([schema.literal('show_all'), schema.literal('show_focused')]) ), - time_field: stringOptionalNullable, + time_field: fieldObject, time_range_mode: stringOptionalNullable, type: schema.oneOf([ schema.literal('table'), diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/agg.tsx b/src/plugins/vis_type_timeseries/public/application/components/aggs/agg.tsx index e5236c3833b19..f027e52a9220d 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/agg.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/agg.tsx @@ -59,6 +59,10 @@ export function Agg(props: AggProps) { ...props.style, }; + const indexPattern = + (props.series.override_index_pattern && props.series.series_index_pattern) || + props.panel.index_pattern; + return (
diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/calculation.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/calculation.js index 5bf4fb55ee5e5..7d8e71f9e002d 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/calculation.js +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/calculation.js @@ -44,7 +44,7 @@ const checkModel = (model) => Array.isArray(model.variables) && model.script !== export function CalculationAgg(props) { const htmlId = htmlIdGenerator(); - const { siblings, model } = props; + const { siblings, model, indexPattern, fields } = props; const handleChange = createChangeHandler(props.onChange, model); const handleSelectChange = createSelectHandler(handleChange); @@ -97,6 +97,8 @@ export function CalculationAgg(props) { @@ -93,6 +95,7 @@ export function CumulativeSumAgg(props) { CumulativeSumAgg.propTypes = { disableDelete: PropTypes.bool, fields: PropTypes.object, + indexPattern: PropTypes.string, model: PropTypes.object, onAdd: PropTypes.func, onChange: PropTypes.func, diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/derivative.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/derivative.js index fa1289dc74c72..c07e7ae024bb2 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/derivative.js +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/derivative.js @@ -38,7 +38,7 @@ import { import { FormattedMessage } from '@kbn/i18n/react'; export const DerivativeAgg = (props) => { - const { siblings } = props; + const { siblings, fields, indexPattern } = props; const defaults = { unit: '' }; const model = { ...defaults, ...props.model }; @@ -91,6 +91,7 @@ export const DerivativeAgg = (props) => { onChange={handleSelectChange('field')} metrics={siblings} metric={model} + fields={fields[indexPattern]} value={model.field} exclude={[METRIC_TYPES.TOP_HIT]} fullWidth @@ -120,6 +121,7 @@ export const DerivativeAgg = (props) => { DerivativeAgg.propTypes = { disableDelete: PropTypes.bool, fields: PropTypes.object, + indexPattern: PropTypes.string, model: PropTypes.object, onAdd: PropTypes.func, onChange: PropTypes.func, diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/field_select.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/field_select.js deleted file mode 100644 index b1ff749494b10..0000000000000 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/field_select.js +++ /dev/null @@ -1,115 +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. - */ - -import PropTypes from 'prop-types'; -import React from 'react'; -import { EuiComboBox } from '@elastic/eui'; -import { injectI18n } from '@kbn/i18n/react'; -import { isFieldEnabled } from '../../lib/check_ui_restrictions'; -import { i18n } from '@kbn/i18n'; - -const isFieldTypeEnabled = (fieldRestrictions, fieldType) => - fieldRestrictions.length ? fieldRestrictions.includes(fieldType) : true; - -function FieldSelectUi({ - type, - fields, - indexPattern, - value, - onChange, - disabled, - restrict, - placeholder, - uiRestrictions, - ...rest -}) { - if (type === 'count') { - return null; - } - - const selectedOptions = []; - const options = Object.values( - (fields[indexPattern] || []).reduce((acc, field) => { - if ( - isFieldTypeEnabled(restrict, field.type) && - isFieldEnabled(field.name, type, uiRestrictions) - ) { - const item = { - label: field.name, - value: field.name, - }; - - if (acc[field.type]) { - acc[field.type].options.push(item); - } else { - acc[field.type] = { - options: [item], - label: field.type, - }; - } - - if (value === item.value) { - selectedOptions.push(item); - } - } - - return acc; - }, {}) - ); - - if (onChange && value && !selectedOptions.length) { - onChange(); - } - - return ( - - ); -} - -FieldSelectUi.defaultProps = { - indexPattern: '', - disabled: false, - restrict: [], - placeholder: i18n.translate('visTypeTimeseries.fieldSelect.selectFieldPlaceholder', { - defaultMessage: 'Select field...', - }), -}; - -FieldSelectUi.propTypes = { - disabled: PropTypes.bool, - fields: PropTypes.object, - id: PropTypes.string, - indexPattern: PropTypes.string, - onChange: PropTypes.func, - restrict: PropTypes.array, - type: PropTypes.string, - value: PropTypes.string, - uiRestrictions: PropTypes.object, - placeholder: PropTypes.string, -}; - -export const FieldSelect = injectI18n(FieldSelectUi); diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/field_select.tsx b/src/plugins/vis_type_timeseries/public/application/components/aggs/field_select.tsx new file mode 100644 index 0000000000000..559db6dac8155 --- /dev/null +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/field_select.tsx @@ -0,0 +1,139 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiComboBox, EuiComboBoxProps, EuiComboBoxOptionOption } from '@elastic/eui'; +import { METRIC_TYPES } from '../../../../common/metric_types'; + +import type { SanitizedFieldType } from '../../../../common/types'; +import type { TimeseriesUIRestrictions } from '../../../../common/ui_restrictions'; + +// @ts-ignore +import { isFieldEnabled } from '../../lib/check_ui_restrictions'; + +interface FieldSelectProps { + type: string; + fields: Record; + indexPattern: string; + value: string; + onChange: (options: Array>) => void; + disabled?: boolean; + restrict?: string[]; + placeholder?: string; + uiRestrictions?: TimeseriesUIRestrictions; + 'data-test-subj'?: string; +} + +const defaultPlaceholder = i18n.translate('visTypeTimeseries.fieldSelect.selectFieldPlaceholder', { + defaultMessage: 'Select field...', +}); + +const isFieldTypeEnabled = (fieldRestrictions: string[], fieldType: string) => + fieldRestrictions.length ? fieldRestrictions.includes(fieldType) : true; + +const sortByLabel = (a: EuiComboBoxOptionOption, b: EuiComboBoxOptionOption) => { + const getNormalizedString = (option: EuiComboBoxOptionOption) => + (option.label || '').toLowerCase(); + + return getNormalizedString(a).localeCompare(getNormalizedString(b)); +}; + +export function FieldSelect({ + type, + fields, + indexPattern = '', + value = '', + onChange, + disabled = false, + restrict = [], + placeholder = defaultPlaceholder, + uiRestrictions, + 'data-test-subj': dataTestSubj = 'metricsIndexPatternFieldsSelect', +}: FieldSelectProps) { + if (type === METRIC_TYPES.COUNT) { + return null; + } + + const selectedOptions: Array> = []; + let newPlaceholder = placeholder; + const groupedOptions: EuiComboBoxProps['options'] = Object.values( + (fields[indexPattern] || []).reduce>>( + (acc, field) => { + if (placeholder === field?.name) { + newPlaceholder = field.label ?? field.name; + } + + if ( + isFieldTypeEnabled(restrict, field.type) && + isFieldEnabled(field.name, type, uiRestrictions) + ) { + const item: EuiComboBoxOptionOption = { + value: field.name, + label: field.label ?? field.name, + }; + + const fieldTypeOptions = acc[field.type]?.options; + + if (fieldTypeOptions) { + fieldTypeOptions.push(item); + } else { + acc[field.type] = { + options: [item], + label: field.type, + }; + } + + if (value === item.value) { + selectedOptions.push(item); + } + } + + return acc; + }, + {} + ) + ); + + // sort groups + groupedOptions.sort(sortByLabel); + + // sort items + groupedOptions.forEach((group) => { + if (Array.isArray(group.options)) { + group.options.sort(sortByLabel); + } + }); + + if (value && !selectedOptions.length) { + onChange([]); + } + + return ( + + ); +} diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/filter_ratio.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/filter_ratio.js index 1c7ab65ecd298..06887f67db84d 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/filter_ratio.js +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/filter_ratio.js @@ -24,6 +24,7 @@ import { FieldSelect } from './field_select'; import { AggRow } from './agg_row'; import { createChangeHandler } from '../lib/create_change_handler'; import { createSelectHandler } from '../lib/create_select_handler'; + import { htmlIdGenerator, EuiFlexGroup, diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/math.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/math.js index 20fc88ba724bc..dd64d27fed918 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/math.js +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/math.js @@ -42,7 +42,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; const checkModel = (model) => Array.isArray(model.variables) && model.script !== undefined; export function MathAgg(props) { - const { siblings, model } = props; + const { siblings, model, fields, indexPattern } = props; const htmlId = htmlIdGenerator(); const handleChange = createChangeHandler(props.onChange, model); @@ -95,6 +95,8 @@ export function MathAgg(props) { { - if (includes(exclude, metric.type)) return false; + if (exclude.includes(metric.type)) { + return false; + } switch (restrict) { case 'basic': - return includes(basicAggs, metric.type); + return basicAggs.includes(metric.type); default: return true; } @@ -55,21 +57,20 @@ export function filterRows(includeSiblings) { }; } -function MetricSelectUi(props) { +export function MetricSelect(props) { const { additionalOptions, restrict, metric, + fields, metrics, onChange, value, exclude, includeSiblings, clearable, - intl, ...rest } = props; - const calculatedMetrics = metrics.filter(createTypeFilter(restrict, exclude)); const siblings = calculateSiblings(calculatedMetrics, metric); @@ -80,7 +81,7 @@ function MetricSelectUi(props) { const percentileOptions = siblings .filter((row) => /^percentile/.test(row.type)) .reduce((acc, row) => { - const label = calculateLabel(row, calculatedMetrics); + const label = calculateLabel(row, calculatedMetrics, fields); switch (row.type) { case METRIC_TYPES.PERCENTILE_RANK: @@ -110,7 +111,7 @@ function MetricSelectUi(props) { }, []); const options = siblings.filter(filterRows(includeSiblings)).map((row) => { - const label = calculateLabel(row, calculatedMetrics); + const label = calculateLabel(row, calculatedMetrics, fields); return { value: row.id, label }; }); const allOptions = [...options, ...additionalOptions, ...percentileOptions]; @@ -122,8 +123,7 @@ function MetricSelectUi(props) { return ( type === MODEL_TYPES.WEIGHTED_EXPONENTIAL_TRIPLE && period * 2 > window; export const MovingAverageAgg = (props) => { - const { siblings } = props; + const { siblings, fields, indexPattern } = props; const model = { ...DEFAULTS, ...props.model }; const modelOptions = [ @@ -153,6 +153,7 @@ export const MovingAverageAgg = (props) => { onChange={handleSelectChange('field')} metrics={siblings} metric={model} + fields={fields[indexPattern]} value={model.field} exclude={[METRIC_TYPES.TOP_HIT]} /> @@ -315,6 +316,7 @@ export const MovingAverageAgg = (props) => { MovingAverageAgg.propTypes = { disableDelete: PropTypes.bool, fields: PropTypes.object, + indexPattern: PropTypes.string, model: PropTypes.object, onAdd: PropTypes.func, onChange: PropTypes.func, diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/percentile_rank.tsx b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/percentile_rank.tsx index f78df9b1ddef4..9de0344f92cc6 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/percentile_rank.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/percentile_rank.tsx @@ -40,8 +40,8 @@ import { createNumberHandler } from '../../lib/create_number_handler'; import { AggRow } from '../agg_row'; import { PercentileRankValues } from './percentile_rank_values'; -import { IFieldType, KBN_FIELD_TYPES } from '../../../../../../../plugins/data/public'; -import { MetricsItemsSchema, PanelSchema, SeriesItemsSchema } from '../../../../../common/types'; +import { KBN_FIELD_TYPES } from '../../../../../../../plugins/data/public'; +import { MetricsItemsSchema, PanelSchema, SanitizedFieldType } from '../../../../../common/types'; import { DragHandleProps } from '../../../../types'; import { PercentileHdr } from '../percentile_hdr'; @@ -49,10 +49,10 @@ const RESTRICT_FIELDS = [KBN_FIELD_TYPES.NUMBER, KBN_FIELD_TYPES.HISTOGRAM]; interface PercentileRankAggProps { disableDelete: boolean; - fields: IFieldType[]; + fields: Record; + indexPattern: string; model: MetricsItemsSchema; panel: PanelSchema; - series: SeriesItemsSchema; siblings: MetricsItemsSchema[]; dragHandleProps: DragHandleProps; onAdd(): void; @@ -61,12 +61,10 @@ interface PercentileRankAggProps { } export const PercentileRankAgg = (props: PercentileRankAggProps) => { - const { series, panel, fields } = props; + const { panel, fields, indexPattern } = props; const defaults = { values: [''] }; const model = { ...defaults, ...props.model }; - const indexPattern = - (series.override_index_pattern && series.series_index_pattern) || panel.index_pattern; const htmlId = htmlIdGenerator(); const isTablePanel = panel.type === 'table'; const handleChange = createChangeHandler(props.onChange, model); @@ -79,7 +77,6 @@ export const PercentileRankAgg = (props: PercentileRankAggProps) => { values, }); }; - return ( { type={model.type} restrict={RESTRICT_FIELDS} indexPattern={indexPattern} - value={model.field} + value={model.field ?? ''} onChange={handleSelectChange('field')} /> diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/positive_only.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/positive_only.js index 6ca5fa8e7447f..481a9cbd22ea0 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/positive_only.js +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/positive_only.js @@ -36,7 +36,7 @@ import { import { FormattedMessage } from '@kbn/i18n/react'; export const PositiveOnlyAgg = (props) => { - const { siblings } = props; + const { siblings, fields, indexPattern } = props; const defaults = { unit: '' }; const model = { ...defaults, ...props.model }; @@ -85,6 +85,7 @@ export const PositiveOnlyAgg = (props) => { onChange={handleSelectChange('field')} metrics={siblings} metric={model} + fields={fields[indexPattern]} value={model.field} exclude={[METRIC_TYPES.TOP_HIT]} /> @@ -98,6 +99,7 @@ export const PositiveOnlyAgg = (props) => { PositiveOnlyAgg.propTypes = { disableDelete: PropTypes.bool, fields: PropTypes.object, + indexPattern: PropTypes.string, model: PropTypes.object, onAdd: PropTypes.func, onChange: PropTypes.func, diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/serial_diff.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/serial_diff.js index e3a0c74273539..31ad0c432bc2d 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/serial_diff.js +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/serial_diff.js @@ -37,7 +37,7 @@ import { import { FormattedMessage } from '@kbn/i18n/react'; export const SerialDiffAgg = (props) => { - const { siblings } = props; + const { siblings, fields, indexPattern } = props; const defaults = { lag: '' }; const model = { ...defaults, ...props.model }; @@ -87,6 +87,7 @@ export const SerialDiffAgg = (props) => { onChange={handleSelectChange('field')} metrics={siblings} metric={model} + fields={fields[indexPattern]} value={model.field} exclude={[METRIC_TYPES.TOP_HIT]} /> @@ -125,6 +126,7 @@ export const SerialDiffAgg = (props) => { SerialDiffAgg.propTypes = { disableDelete: PropTypes.bool, fields: PropTypes.object, + indexPattern: PropTypes.string, model: PropTypes.object, onAdd: PropTypes.func, onChange: PropTypes.func, diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/std_agg.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/std_agg.js index b882981f6b5c7..fb8b31834048a 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/std_agg.js +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/std_agg.js @@ -37,8 +37,10 @@ import { getSupportedFieldsByMetricType } from '../lib/get_supported_fields_by_m export function StandardAgg(props) { const { model, panel, series, fields, uiRestrictions } = props; + const handleChange = createChangeHandler(props.onChange, model); const handleSelectChange = createSelectHandler(handleChange); + const restrictFields = getSupportedFieldsByMetricType(model.type); const indexPattern = (series.override_index_pattern && series.series_index_pattern) || panel.index_pattern; diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/std_sibling.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/std_sibling.js index bed5e9caa9f87..456e03eeea1c9 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/std_sibling.js +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/std_sibling.js @@ -40,7 +40,7 @@ import { import { injectI18n, FormattedMessage } from '@kbn/i18n/react'; const StandardSiblingAggUi = (props) => { - const { siblings, intl } = props; + const { siblings, intl, fields, indexPattern } = props; const defaults = { sigma: '' }; const model = { ...defaults, ...props.model }; const htmlId = htmlIdGenerator(); @@ -158,6 +158,7 @@ const StandardSiblingAggUi = (props) => { onChange={handleSelectChange('field')} exclude={[METRIC_TYPES.PERCENTILE, METRIC_TYPES.TOP_HIT]} metrics={siblings} + fields={fields[indexPattern]} metric={model} value={model.field} /> @@ -173,6 +174,7 @@ const StandardSiblingAggUi = (props) => { StandardSiblingAggUi.propTypes = { disableDelete: PropTypes.bool, fields: PropTypes.object, + indexPattern: PropTypes.string, model: PropTypes.object, onAdd: PropTypes.func, onChange: PropTypes.func, diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/vars.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/vars.js index 15b02b067e353..bae839fe9ad11 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/vars.js +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/vars.js @@ -70,6 +70,7 @@ export class CalculationVars extends Component { metrics={this.props.metrics} metric={this.props.model} value={row.field} + fields={this.props.fields[this.props.indexPattern]} includeSiblings={this.props.includeSiblings} exclude={this.props.exclude} /> @@ -105,6 +106,8 @@ CalculationVars.defaultProps = { }; CalculationVars.propTypes = { + fields: PropTypes.object, + indexPattern: PropTypes.string, metrics: PropTypes.array, model: PropTypes.object, name: PropTypes.string, diff --git a/src/plugins/vis_type_timeseries/public/application/components/annotations_editor.js b/src/plugins/vis_type_timeseries/public/application/components/annotations_editor.js index 3d38aa72fc271..dcdc2324c9b0a 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/annotations_editor.js +++ b/src/plugins/vis_type_timeseries/public/application/components/annotations_editor.js @@ -74,6 +74,7 @@ export class AnnotationsEditor extends Component { handleChange(_.assign({}, item, part)); }; } + handleQueryChange = (model, filter) => { const part = { query_string: filter }; collectionActions.handleChange(this.props, { diff --git a/src/plugins/vis_type_timeseries/public/application/components/index_pattern.js b/src/plugins/vis_type_timeseries/public/application/components/index_pattern.js index e976519dfe635..ab234be28abea 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/index_pattern.js +++ b/src/plugins/vis_type_timeseries/public/application/components/index_pattern.js @@ -78,10 +78,6 @@ export const IndexPattern = ({ allowLevelofDetail, }) => { const config = getUISettings(); - - const handleSelectChange = createSelectHandler(onChange); - const handleTextChange = createTextHandler(onChange); - const timeFieldName = `${prefix}time_field`; const indexPatternName = `${prefix}index_pattern`; const intervalName = `${prefix}interval`; @@ -100,6 +96,9 @@ export const IndexPattern = ({ [onChange, maxBarsName] ); + const handleSelectChange = createSelectHandler(onChange); + const handleTextChange = createTextHandler(onChange); + const timeRangeOptions = [ { label: i18n.translate('visTypeTimeseries.indexPattern.timeRange.lastValue', { @@ -119,7 +118,7 @@ export const IndexPattern = ({ const defaults = { default_index_pattern: '', - [indexPatternName]: '*', + [indexPatternName]: '', [intervalName]: AUTO_INTERVAL, [dropBucketName]: 1, [maxBarsName]: config.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET), @@ -191,7 +190,7 @@ export const IndexPattern = ({ data-test-subj="metricsIndexPatternInput" disabled={disabled} placeholder={model.default_index_pattern} - onChange={handleTextChange(indexPatternName, '*')} + onChange={handleTextChange(indexPatternName)} value={model[indexPatternName]} /> @@ -204,7 +203,6 @@ export const IndexPattern = ({ })} > { - let handleChange; - let changeHandler; +describe('createSelectHandler', () => { + describe('createSelectHandler()', () => { + let handleChange: HandleChange; + let changeHandler: ReturnType; - beforeEach(() => { - handleChange = jest.fn(); - changeHandler = createSelectHandler(handleChange); - const fn = changeHandler('test'); - fn([{ value: 'foo' }]); - }); + beforeEach(() => { + handleChange = jest.fn(); + changeHandler = createSelectHandler(handleChange); + }); + + test('should calls handleChange() function with the correct data', () => { + const fn = changeHandler('test'); + + fn([{ value: 'foo', label: 'foo' }]); - test('calls handleChange() function with partial', () => { - expect(handleChange.mock.calls.length).toEqual(1); - expect(handleChange.mock.calls[0][0]).toEqual({ - test: 'foo', + expect(handleChange).toHaveBeenCalledWith({ + test: 'foo', + }); }); }); }); diff --git a/src/plugins/vis_type_timeseries/common/model_options.test.js b/src/plugins/vis_type_timeseries/public/application/components/lib/create_select_handler.ts similarity index 71% rename from src/plugins/vis_type_timeseries/common/model_options.test.js rename to src/plugins/vis_type_timeseries/public/application/components/lib/create_select_handler.ts index 7d01226bdc040..15f4e19702a7f 100644 --- a/src/plugins/vis_type_timeseries/common/model_options.test.js +++ b/src/plugins/vis_type_timeseries/public/application/components/lib/create_select_handler.ts @@ -16,13 +16,13 @@ * specific language governing permissions and limitations * under the License. */ +import { EuiComboBoxOptionOption } from '@elastic/eui'; -import { MODEL_TYPES } from './model_options'; +export type HandleChange = (partialModel: Record) => void; -describe('src/legacy/core_plugins/metrics/common/model_options.js', () => { - describe('MODEL_TYPES', () => { - test('should match a snapshot of constants', () => { - expect(MODEL_TYPES).toMatchSnapshot(); - }); +export const createSelectHandler = (handleChange: HandleChange) => (name: string) => ( + selected: EuiComboBoxOptionOption[] = [] +) => + handleChange?.({ + [name]: selected[0]?.value ?? null, }); -}); diff --git a/src/plugins/vis_type_timeseries/public/application/components/lib/series_change_handler.js b/src/plugins/vis_type_timeseries/public/application/components/lib/series_change_handler.js index b6b99d7782762..854d9bf5c59bc 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/lib/series_change_handler.js +++ b/src/plugins/vis_type_timeseries/public/application/components/lib/series_change_handler.js @@ -17,7 +17,6 @@ * under the License. */ -import _ from 'lodash'; import { newMetricAggFn } from './new_metric_agg_fn'; import { isBasicAgg } from '../../../../common/agg_lookup'; import { handleAdd, handleChange } from './collection_actions'; @@ -30,8 +29,10 @@ export const seriesChangeHandler = (props, items) => (doc) => { handleAdd.call(null, props, () => { const metric = newMetricAggFn(); metric.type = doc.type; - const incompatPipelines = ['calculation', 'series_agg']; - if (!_.includes(incompatPipelines, doc.type)) metric.field = doc.id; + + if (!['calculation', 'series_agg'].includes(doc.type)) { + metric.field = doc.id; + } return metric; }); } else { diff --git a/src/plugins/vis_type_timeseries/public/application/components/panel_config/markdown.js b/src/plugins/vis_type_timeseries/public/application/components/panel_config/markdown.js index ef7aec61a2f0d..9a59c3ece5849 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/panel_config/markdown.js +++ b/src/plugins/vis_type_timeseries/public/application/components/panel_config/markdown.js @@ -46,7 +46,7 @@ const lessC = less(window, { env: 'production' }); import { injectI18n, FormattedMessage } from '@kbn/i18n/react'; import { QueryBarWrapper } from '../query_bar_wrapper'; import { getDefaultQueryLanguage } from '../lib/get_default_query_language'; -import { VisDataContext } from './../../contexts/vis_data_context'; +import { VisDataContext } from '../../contexts/vis_data_context'; class MarkdownPanelConfigUi extends Component { constructor(props) { diff --git a/src/plugins/vis_type_timeseries/public/application/components/panel_config/table.js b/src/plugins/vis_type_timeseries/public/application/components/panel_config/table.js index b2ea90d6a87fe..16bc4b0631396 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/panel_config/table.js +++ b/src/plugins/vis_type_timeseries/public/application/components/panel_config/table.js @@ -45,7 +45,7 @@ import { import { FormattedMessage } from '@kbn/i18n/react'; import { QueryBarWrapper } from '../query_bar_wrapper'; import { getDefaultQueryLanguage } from '../lib/get_default_query_language'; -import { VisDataContext } from './../../contexts/vis_data_context'; +import { VisDataContext } from '../../contexts/vis_data_context'; import { BUCKET_TYPES } from '../../../../common/metric_types'; export class TablePanelConfig extends Component { static contextType = VisDataContext; diff --git a/src/plugins/vis_type_timeseries/public/application/components/splits/__snapshots__/terms.test.js.snap b/src/plugins/vis_type_timeseries/public/application/components/splits/__snapshots__/terms.test.js.snap index daff68e40dbae..09cd6d550fd96 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/splits/__snapshots__/terms.test.js.snap +++ b/src/plugins/vis_type_timeseries/public/application/components/splits/__snapshots__/terms.test.js.snap @@ -43,7 +43,7 @@ exports[`src/legacy/core_plugins/metrics/public/components/splits/terms.test.js } labelType="label" > - - { this.setState({ @@ -191,6 +189,31 @@ export class VisEditor extends Component { } componentDidMount() { + const dataStart = getDataStart(); + + dataStart.indexPatterns.getDefault().then(async (index) => { + const defaultIndexTitle = index?.title ?? ''; + const indexPatterns = extractIndexPatterns(this.props.visParams, defaultIndexTitle); + + this.setState({ + model: { + ...this.props.visParams, + /** @legacy + * please use IndexPatterns service instead + * **/ + default_index_pattern: defaultIndexTitle, + /** @legacy + * please use IndexPatterns service instead + * **/ + default_timefield: index?.timeFieldName ?? '', + }, + dirty: false, + autoApply: true, + visFields: await fetchFields(indexPatterns), + extractedIndexPatterns: [''], + }); + }); + this.props.eventEmitter.on('updateEditor', this.updateModel); } @@ -207,10 +230,8 @@ VisEditor.defaultProps = { VisEditor.propTypes = { vis: PropTypes.object, visData: PropTypes.object, - visFields: PropTypes.object, renderComplete: PropTypes.func, config: PropTypes.object, - savedObj: PropTypes.object, timeRange: PropTypes.object, appState: PropTypes.object, }; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/vis.js index a31be694cd172..46f266f631911 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/vis.js @@ -22,7 +22,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { RedirectAppLinks } from '../../../../../../kibana_react/public'; import { createTickFormatter } from '../../lib/tick_formatter'; -import { calculateLabel } from '../../../../../common/calculate_label'; import { isSortable } from './is_sortable'; import { EuiToolTip, EuiIcon } from '@elastic/eui'; import { replaceVars } from '../../lib/replace_vars'; @@ -30,8 +29,6 @@ import { fieldFormats } from '../../../../../../../plugins/data/public'; import { FormattedMessage } from '@kbn/i18n/react'; import { getFieldFormats, getCoreStart } from '../../../../services'; -import { METRIC_TYPES } from '../../../../../common/metric_types'; - function getColor(rules, colorKey, value) { let color; if (rules) { @@ -109,30 +106,19 @@ class TableVis extends Component { }; renderHeader() { - const { model, uiState, onUiState } = this.props; + const { model, uiState, onUiState, visData } = this.props; const stateKey = `${model.type}.sort`; const sort = uiState.get(stateKey, { column: '_default_', order: 'asc', }); - const calculateHeaderLabel = (metric, item) => { - const defaultLabel = item.label || calculateLabel(metric, item.metrics); - - switch (metric.type) { - case METRIC_TYPES.PERCENTILE: - return `${defaultLabel} (${last(metric.percentiles).value || 0})`; - case METRIC_TYPES.PERCENTILE_RANK: - return `${defaultLabel} (${last(metric.values) || 0})`; - default: - return defaultLabel; - } - }; + const calculateHeaderLabel = (metric, item) => + item.label || visData.series[0]?.series?.find((s) => item.id === s.id)?.label; const columns = this.visibleSeries.map((item) => { const metric = last(item.metrics); const label = calculateHeaderLabel(metric, item); - const handleClick = () => { if (!isSortable(metric)) return; let order; @@ -179,7 +165,7 @@ class TableVis extends Component { ); }); - const label = model.pivot_label || model.pivot_field || model.pivot_id; + const label = visData.pivot_label || model.pivot_label || model.pivot_id; let sortIcon; if (sort.column === '_default_') { sortIcon = sort.order === 'asc' ? 'sortUp' : 'sortDown'; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_with_splits.js b/src/plugins/vis_type_timeseries/public/application/components/vis_with_splits.js index 27891cdbb3943..8438b6899e835 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_with_splits.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_with_splits.js @@ -20,8 +20,7 @@ import React from 'react'; import { getDisplayName } from './lib/get_display_name'; import { labelDateFormatter } from './lib/label_date_formatter'; -import { last, findIndex, first } from 'lodash'; -import { calculateLabel } from '../../../common/calculate_label'; +import { findIndex, first } from 'lodash'; export function visWithSplits(WrappedComponent) { function SplitVisComponent(props) { @@ -35,8 +34,8 @@ export function visWithSplits(WrappedComponent) { const [seriesId, splitId] = series.id.split(':'); const seriesModel = model.series.find((s) => s.id === seriesId); if (!seriesModel || !splitId) return acc; - const metric = last(seriesModel.metrics); - const label = calculateLabel(metric, seriesModel.metrics); + + const label = series.splitByLabel; if (!acc[splitId]) { acc[splitId] = { @@ -102,6 +101,7 @@ export function visWithSplits(WrappedComponent) { return
{rows}
; } + SplitVisComponent.displayName = `SplitVisComponent(${getDisplayName(WrappedComponent)})`; return SplitVisComponent; } diff --git a/src/plugins/vis_type_timeseries/public/application/editor_controller.js b/src/plugins/vis_type_timeseries/public/application/editor_controller.js index 548bf2623fc1a..e147f4be6c46f 100644 --- a/src/plugins/vis_type_timeseries/public/application/editor_controller.js +++ b/src/plugins/vis_type_timeseries/public/application/editor_controller.js @@ -19,8 +19,7 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; -import { fetchIndexPatternFields } from './lib/fetch_fields'; -import { getSavedObjectsClient, getUISettings, getI18n } from '../services'; +import { getUISettings, getI18n } from '../services'; import { VisEditor } from './components/vis_editor_lazy'; export class EditorController { @@ -31,42 +30,18 @@ export class EditorController { this.eventEmitter = eventEmitter; this.state = { - fields: [], vis: vis, - isLoaded: false, }; } - fetchDefaultIndexPattern = async () => { - const indexPattern = await getSavedObjectsClient().client.get( - 'index-pattern', - getUISettings().get('defaultIndex') - ); - - return indexPattern.attributes; - }; - - fetchDefaultParams = async () => { - const { title, timeFieldName } = await this.fetchDefaultIndexPattern(); - - this.state.vis.params.default_index_pattern = title; - this.state.vis.params.default_timefield = timeFieldName; - this.state.fields = await fetchIndexPatternFields(this.state.vis); - - this.state.isLoaded = true; - }; - async render(params) { const I18nContext = getI18n().Context; - !this.state.isLoaded && (await this.fetchDefaultParams()); - render( {}} diff --git a/src/plugins/vis_type_timeseries/public/application/lib/fetch_fields.js b/src/plugins/vis_type_timeseries/public/application/lib/fetch_fields.ts similarity index 64% rename from src/plugins/vis_type_timeseries/public/application/lib/fetch_fields.js rename to src/plugins/vis_type_timeseries/public/application/lib/fetch_fields.ts index a32ab71f36357..ae78178af957e 100644 --- a/src/plugins/vis_type_timeseries/public/application/lib/fetch_fields.js +++ b/src/plugins/vis_type_timeseries/public/application/lib/fetch_fields.ts @@ -17,31 +17,43 @@ * under the License. */ import { i18n } from '@kbn/i18n'; -import { extractIndexPatterns } from '../../../common/extract_index_patterns'; -import { getCoreStart } from '../../services'; +import { getCoreStart, getDataStart } from '../../services'; import { ROUTES } from '../../../common/constants'; +import { SanitizedFieldType } from '../../../common/types'; + +export async function fetchFields( + indexes: string[] = [], + signal?: AbortSignal +): Promise> { + const patterns = Array.isArray(indexes) ? indexes : [indexes]; + const coreStart = getCoreStart(); + const dataStart = getDataStart(); -export async function fetchFields(indexPatterns = [], signal) { - const patterns = Array.isArray(indexPatterns) ? indexPatterns : [indexPatterns]; try { + const defaultIndexPattern = await dataStart.indexPatterns.getDefault(); const indexFields = await Promise.all( - patterns.map((pattern) => - getCoreStart().http.get(ROUTES.FIELDS, { + patterns.map(async (pattern) => { + return coreStart.http.get(ROUTES.FIELDS, { query: { index: pattern, }, signal, - }) - ) + }); + }) ); - return patterns.reduce( + const fields: Record = patterns.reduce( (cumulatedFields, currentPattern, index) => ({ ...cumulatedFields, [currentPattern]: indexFields[index], }), {} ); + + if (defaultIndexPattern?.title && patterns.includes(defaultIndexPattern.title)) { + fields[''] = fields[defaultIndexPattern.title]; + } + return fields; } catch (error) { if (error.name !== 'AbortError') { getCoreStart().notifications.toasts.addDanger({ @@ -52,11 +64,5 @@ export async function fetchFields(indexPatterns = [], signal) { }); } } - return []; -} - -export async function fetchIndexPatternFields({ params, fields = {} }) { - const indexPatterns = extractIndexPatterns(params, fields); - - return await fetchFields(indexPatterns); + return {}; } diff --git a/src/plugins/vis_type_timeseries/server/lib/get_fields.ts b/src/plugins/vis_type_timeseries/server/lib/get_fields.ts index 8f87318222f2b..d15332b26701c 100644 --- a/src/plugins/vis_type_timeseries/server/lib/get_fields.ts +++ b/src/plugins/vis_type_timeseries/server/lib/get_fields.ts @@ -16,24 +16,31 @@ * specific language governing permissions and limitations * under the License. */ -import { uniqBy, get } from 'lodash'; +import { uniqBy } from 'lodash'; import { first, map } from 'rxjs/operators'; import { KibanaRequest, RequestHandlerContext } from 'kibana/server'; import { Framework } from '../plugin'; -import { - indexPatterns, - IndexPatternFieldDescriptor, - IndexPatternsFetcher, -} from '../../../data/server'; +import { IndexPatternsFetcher } from '../../../data/server'; import { ReqFacade } from './search_strategies/strategies/abstract_search_strategy'; export async function getFields( requestContext: RequestHandlerContext, request: KibanaRequest, framework: Framework, - indexPattern: string + indexPatternString: string ) { + const getIndexPatternsService = async () => { + const [, { data }] = await framework.core.getStartServices(); + + return await data.indexPatterns.indexPatternsServiceFactory( + requestContext.core.savedObjects.client, + requestContext.core.elasticsearch.client.asCurrentUser + ); + }; + + const indexPatternsService = await getIndexPatternsService(); + // NOTE / TODO: This facade has been put in place to make migrating to the New Platform easier. It // removes the need to refactor many layers of dependencies on "req", and instead just augments the top // level object passed from here. The layers should be refactored fully at some point, but for now @@ -44,7 +51,7 @@ export async function getFields( framework, payload: {}, pre: { - indexPatternsService: new IndexPatternsFetcher( + indexPatternsFetcher: new IndexPatternsFetcher( requestContext.core.elasticsearch.client.asCurrentUser ), }, @@ -58,19 +65,13 @@ export async function getFields( ) .toPromise(); }, + getIndexPatternsService: async () => indexPatternsService, }; - let indexPatternString = indexPattern; if (!indexPatternString) { - const [{ savedObjects, elasticsearch }, { data }] = await framework.core.getStartServices(); - const savedObjectsClient = savedObjects.getScopedClient(request); - const clusterClient = elasticsearch.client.asScoped(request).asCurrentUser; - const indexPatternsService = await data.indexPatterns.indexPatternsServiceFactory( - savedObjectsClient, - clusterClient - ); const defaultIndexPattern = await indexPatternsService.getDefault(); - indexPatternString = get(defaultIndexPattern, 'title', ''); + + indexPatternString = defaultIndexPattern?.title ?? ''; } const { @@ -78,12 +79,10 @@ export async function getFields( capabilities, } = (await framework.searchStrategyRegistry.getViableStrategy(reqFacade, indexPatternString))!; - const fields = ((await searchStrategy.getFieldsForWildcard( + const fields = await searchStrategy.getFieldsForWildcard( reqFacade, indexPatternString, capabilities - )) as IndexPatternFieldDescriptor[]).filter( - (field) => field.aggregatable && !indexPatterns.isNestedField(field) ); return uniqBy(fields, (field) => field.name); diff --git a/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts b/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts index aefbe0ea78d4b..d450bb205c9ce 100644 --- a/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts +++ b/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts @@ -71,6 +71,14 @@ export function getVisData( ) .toPromise(); }, + getIndexPatternsService: async () => { + const [, { data }] = await framework.core.getStartServices(); + + return await data.indexPatterns.indexPatternsServiceFactory( + requestContext.core.savedObjects.client, + requestContext.core.elasticsearch.client.asCurrentUser + ); + }, }; const promises = reqFacade.payload.panels.map(getPanelData(reqFacade)); return Promise.all(promises).then((res) => { diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_strategy_registry.ts b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_strategy_registry.ts index 6fbed1ddfba0f..afe598393ab92 100644 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_strategy_registry.ts +++ b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_strategy_registry.ts @@ -24,7 +24,8 @@ import { DefaultSearchStrategy } from './strategies/default_search_strategy'; import { extractIndexPatterns } from '../../../common/extract_index_patterns'; export type RequestFacade = any; -export type Panel = any; + +import { PanelSchema } from '../../../common/types'; export class SearchStrategyRegistry { private strategies: AbstractSearchStrategy[] = []; @@ -53,8 +54,8 @@ export class SearchStrategyRegistry { } } - async getViableStrategyForPanel(req: RequestFacade, panel: Panel) { - const indexPattern = extractIndexPatterns(panel).join(','); + async getViableStrategyForPanel(req: RequestFacade, panel: PanelSchema) { + const indexPattern = extractIndexPatterns(panel, panel.default_index_pattern).join(','); return this.getViableStrategy(req, indexPattern); } diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.js index 2c38e883cd69f..3e3e654617e76 100644 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.js @@ -26,14 +26,17 @@ describe('AbstractSearchStrategy', () => { let indexPattern; beforeEach(() => { - mockedFields = {}; + mockedFields = []; req = { payload: {}, pre: { - indexPatternsService: { + indexPatternsFetcher: { getFieldsForWildcard: jest.fn().mockReturnValue(mockedFields), }, }, + getIndexPatternsService: jest.fn(() => ({ + find: jest.fn(() => []), + })), }; abstractSearchStrategy = new AbstractSearchStrategy(); @@ -48,9 +51,10 @@ describe('AbstractSearchStrategy', () => { test('should return fields for wildcard', async () => { const fields = await abstractSearchStrategy.getFieldsForWildcard(req, indexPattern); - expect(fields).toBe(mockedFields); - expect(req.pre.indexPatternsService.getFieldsForWildcard).toHaveBeenCalledWith({ + expect(fields).toEqual(mockedFields); + expect(req.pre.indexPatternsFetcher.getFieldsForWildcard).toHaveBeenCalledWith({ pattern: indexPattern, + metaFields: [], fieldCapsOptions: { allow_no_indices: true }, }); }); diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts index 71461d319f2b6..e27241c5eef62 100644 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts +++ b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts @@ -17,16 +17,19 @@ * under the License. */ -import { +import type { RequestHandlerContext, FakeRequest, IUiSettingsClient, SavedObjectsClientContract, } from 'kibana/server'; -import { Framework } from '../../../plugin'; -import { IndexPatternsFetcher } from '../../../../../data/server'; -import { VisPayload } from '../../../../common/types'; +import type { Framework } from '../../../plugin'; +import type { IndexPatternsFetcher, IFieldType } from '../../../../../data/server'; +import type { VisPayload } from '../../../../common/types'; +import type { IndexPatternsService } from '../../../../../data/common'; +import { indexPatterns } from '../../../../../data/server'; +import { SanitizedFieldType } from '../../../../common/types'; /** * ReqFacade is a regular KibanaRequest object extended with additional service @@ -39,13 +42,27 @@ export interface ReqFacade extends FakeRequest { framework: Framework; payload: T; pre: { - indexPatternsService?: IndexPatternsFetcher; + indexPatternsFetcher?: IndexPatternsFetcher; }; getUiSettingsService: () => IUiSettingsClient; getSavedObjectsClient: () => SavedObjectsClientContract; getEsShardTimeout: () => Promise; + getIndexPatternsService: () => Promise; } +const toSanitizedFieldType = (fields: IFieldType[]) => { + return fields + .filter((field) => field.aggregatable && !indexPatterns.isNestedField(field)) + .map( + (field: IFieldType) => + ({ + name: field.name, + label: field.customLabel ?? field.name, + type: field.type, + } as SanitizedFieldType) + ); +}; + export abstract class AbstractSearchStrategy { async search(req: ReqFacade, bodies: any[], indexType?: string) { const requests: any[] = []; @@ -81,13 +98,27 @@ export abstract class AbstractSearchStrategy { async getFieldsForWildcard( req: ReqFacade, indexPattern: string, - capabilities?: unknown + capabilities?: unknown, + options?: Partial<{ + type: string; + rollupIndex: string; + }> ) { - const { indexPatternsService } = req.pre; + const { indexPatternsFetcher } = req.pre; + const indexPatternsService = await req.getIndexPatternsService(); + const kibanaIndexPattern = (await indexPatternsService.find(indexPattern)).find( + (index) => index.title === indexPattern + ); - return await indexPatternsService!.getFieldsForWildcard({ - pattern: indexPattern, - fieldCapsOptions: { allow_no_indices: true }, - }); + return toSanitizedFieldType( + kibanaIndexPattern + ? kibanaIndexPattern.fields.getAll() + : await indexPatternsFetcher!.getFieldsForWildcard({ + pattern: indexPattern, + fieldCapsOptions: { allow_no_indices: true }, + metaFields: [], + ...options, + }) + ); } } diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/default_search_strategy.ts b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/default_search_strategy.ts index e1f519456d373..0744b50c27ca2 100644 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/default_search_strategy.ts +++ b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/default_search_strategy.ts @@ -30,4 +30,12 @@ export class DefaultSearchStrategy extends AbstractSearchStrategy { capabilities: new DefaultSearchCapabilities(req), }); } + + async getFieldsForWildcard( + req: ReqFacade, + indexPattern: string, + capabilities?: unknown + ) { + return super.getFieldsForWildcard(req, indexPattern, capabilities); + } } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/annotations/build_request_body.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/annotations/build_request_body.js index 9ea62e2700517..1e93967bdde9e 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/annotations/build_request_body.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/annotations/build_request_body.js @@ -32,8 +32,8 @@ import { processors } from '../request_processors/annotations'; * ] * @returns {Object} doc - processed body */ -export function buildAnnotationRequest(...args) { +export async function buildAnnotationRequest(...args) { const processor = buildProcessorFunction(processors, ...args); - const doc = processor({}); + const doc = await processor({}); return doc; } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/annotations/get_request_params.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/annotations/get_request_params.js index 1b2334c7dea94..16099ccd6dba4 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/annotations/get_request_params.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/annotations/get_request_params.js @@ -19,7 +19,6 @@ import { buildAnnotationRequest } from './build_request_body'; import { getEsShardTimeout } from '../helpers/get_es_shard_timeout'; import { getIndexPatternObject } from '../helpers/get_index_pattern'; -import { UI_SETTINGS } from '../../../../../data/common'; export async function getAnnotationRequestParams( req, @@ -32,17 +31,14 @@ export async function getAnnotationRequestParams( const esShardTimeout = await getEsShardTimeout(req); const indexPattern = annotation.index_pattern; const { indexPatternObject, indexPatternString } = await getIndexPatternObject(req, indexPattern); - const request = buildAnnotationRequest( + const request = await buildAnnotationRequest( req, panel, annotation, esQueryConfig, indexPatternObject, capabilities, - { - maxBarsUiSettings: await uiSettings.get(UI_SETTINGS.HISTOGRAM_MAX_BARS), - barTargetUiSettings: await uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET), - } + uiSettings ); return { diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/get_series_data.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/get_series_data.js index 232efc7514a5a..f699a50db66af 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/get_series_data.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/get_series_data.js @@ -45,11 +45,14 @@ export async function getSeriesData(req, panel) { ); const data = await searchStrategy.search(req, searches); - const handleResponseBodyFn = handleResponseBody(panel); + const handleResponseBodyFn = handleResponseBody(panel, req, searchStrategy, capabilities); - const series = data.map((resp) => - handleResponseBodyFn(resp.rawResponse ? resp.rawResponse : resp) + const series = await Promise.all( + data.map( + async (resp) => await handleResponseBodyFn(resp.rawResponse ? resp.rawResponse : resp) + ) ); + let annotations = null; if (panel.annotations && panel.annotations.length) { diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/get_table_data.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/get_table_data.js index eaaa5a9605b4b..a7b304e5e5866 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/get_table_data.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/get_table_data.js @@ -16,13 +16,15 @@ * specific language governing permissions and limitations * under the License. */ + import { buildRequestBody } from './table/build_request_body'; import { handleErrorResponse } from './handle_error_response'; import { get } from 'lodash'; import { processBucket } from './table/process_bucket'; import { getEsQueryConfig } from './helpers/get_es_query_uisettings'; import { getIndexPatternObject } from './helpers/get_index_pattern'; -import { UI_SETTINGS } from '../../../../data/common'; +import { createFieldsFetcher } from './helpers/fields_fetcher'; +import { extractFieldLabel } from '../../../common/calculate_label'; export async function getTableData(req, panel) { const panelIndexPattern = panel.index_pattern; @@ -33,18 +35,33 @@ export async function getTableData(req, panel) { } = await req.framework.searchStrategyRegistry.getViableStrategy(req, panelIndexPattern); const esQueryConfig = await getEsQueryConfig(req); const { indexPatternObject } = await getIndexPatternObject(req, panelIndexPattern); + const extractFields = createFieldsFetcher(req, searchStrategy, capabilities); + + const calculatePivotLabel = async () => { + if (panel.pivot_id && indexPatternObject?.title) { + const fields = await extractFields(indexPatternObject.title); + + return extractFieldLabel(fields, panel.pivot_id); + } + return panel.pivot_id; + }; const meta = { type: panel.type, + pivot_label: panel.pivot_label || (await calculatePivotLabel()), uiRestrictions: capabilities.uiRestrictions, }; try { const uiSettings = req.getUiSettingsService(); - const body = buildRequestBody(req, panel, esQueryConfig, indexPatternObject, capabilities, { - maxBarsUiSettings: await uiSettings.get(UI_SETTINGS.HISTOGRAM_MAX_BARS), - barTargetUiSettings: await uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET), - }); + const body = await buildRequestBody( + req, + panel, + esQueryConfig, + indexPatternObject, + capabilities, + uiSettings + ); const [resp] = await searchStrategy.search(req, [ { @@ -59,9 +76,13 @@ export async function getTableData(req, panel) { [] ); + const series = await Promise.all( + buckets.map(processBucket(panel, req, searchStrategy, capabilities, extractFields)) + ); + return { ...meta, - series: buckets.map(processBucket(panel)), + series, }; } catch (err) { if (err.body || err.name === 'KQLSyntaxError') { diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/bucket_transform.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/bucket_transform.js index dc2936072165e..431b5fb83d831 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/bucket_transform.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/bucket_transform.js @@ -128,7 +128,8 @@ export const bucketTransform = { }, }; if (bucket.order_by) { - set(body, 'aggs.docs.top_hits.sort', [{ [bucket.order_by]: { order: bucket.order } }]); + const orderField = bucket.order_by; + set(body, 'aggs.docs.top_hits.sort', [{ [orderField]: { order: bucket.order } }]); } return body; }, diff --git a/src/plugins/vis_type_timeseries/public/application/components/lib/create_select_handler.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/fields_fetcher.ts similarity index 59% rename from src/plugins/vis_type_timeseries/public/application/components/lib/create_select_handler.js rename to src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/fields_fetcher.ts index ff6c2cc0767f5..6ee90eabf9f02 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/lib/create_select_handler.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/fields_fetcher.ts @@ -17,12 +17,24 @@ * under the License. */ -import _ from 'lodash'; +import { AbstractSearchStrategy, DefaultSearchCapabilities, ReqFacade } from '../../..'; -export const createSelectHandler = (handleChange) => { - return (name) => (selectedOptions) => { - return handleChange?.({ - [name]: _.get(selectedOptions, '[0].value', null), - }); +export const createFieldsFetcher = ( + req: ReqFacade, + searchStrategy: AbstractSearchStrategy, + capabilities: DefaultSearchCapabilities +) => { + const fieldsCacheMap = new Map(); + + return async (index: string) => { + if (fieldsCacheMap.has(index)) { + return fieldsCacheMap.get(index); + } + + const fields = await searchStrategy.getFieldsForWildcard(req, index, capabilities); + + fieldsCacheMap.set(index, fields); + + return fields; }; }; diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_splits.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_splits.js index 6c162e327fb21..e491a6795ba5d 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_splits.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_splits.js @@ -27,7 +27,7 @@ import { formatKey } from './format_key'; const getTimeSeries = (resp, series) => _.get(resp, `aggregations.timeseries`) || _.get(resp, `aggregations.${series.id}.timeseries`); -export function getSplits(resp, panel, series, meta) { +export async function getSplits(resp, panel, series, meta, extractFields) { if (!meta) { meta = _.get(resp, `aggregations.${series.id}.meta`); } @@ -35,12 +35,17 @@ export function getSplits(resp, panel, series, meta) { const color = new Color(series.color); const metric = getLastMetric(series); const buckets = _.get(resp, `aggregations.${series.id}.buckets`); + + const fieldsForMetaIndex = meta.index ? await extractFields(meta.index) : []; + const splitByLabel = calculateLabel(metric, series.metrics, fieldsForMetaIndex); + if (buckets) { if (Array.isArray(buckets)) { const size = buckets.length; const colors = getSplitColors(series.color, size, series.split_color_mode); return buckets.map((bucket) => { bucket.id = `${series.id}:${bucket.key}`; + bucket.splitByLabel = splitByLabel; bucket.label = formatKey(bucket.key, series); bucket.labelFormatted = bucket.key_as_string ? formatKey(bucket.key_as_string, series) : ''; bucket.color = panel.type === 'top_n' ? color.string() : colors.shift(); @@ -72,10 +77,12 @@ export function getSplits(resp, panel, series, meta) { .forEach((m) => { mergeObj[m.id] = _.get(resp, `aggregations.${series.id}.${m.id}`); }); + return [ { id: series.id, - label: series.label || calculateLabel(metric, series.metrics), + splitByLabel, + label: series.label || splitByLabel, color: color.string(), ...mergeObj, meta, diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_splits.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_splits.test.js index 5ccd61a1c9102..dac269ed2f6c3 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_splits.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_splits.test.js @@ -20,7 +20,7 @@ import { getSplits } from './get_splits'; describe('getSplits(resp, panel, series)', () => { - test('should return a splits for everything/filter group bys', () => { + test('should return a splits for everything/filter group bys', async () => { const resp = { aggregations: { SERIES: { @@ -40,19 +40,20 @@ describe('getSplits(resp, panel, series)', () => { { id: 'SIBAGG', type: 'avg_bucket', field: 'AVG' }, ], }; - expect(getSplits(resp, panel, series)).toEqual([ + expect(await getSplits(resp, panel, series, undefined)).toEqual([ { id: 'SERIES', label: 'Overall Average of Average of cpu', meta: { bucketSize: 10 }, color: 'rgb(255, 0, 0)', + splitByLabel: 'Overall Average of Average of cpu', timeseries: { buckets: [] }, SIBAGG: { value: 1 }, }, ]); }); - test('should return a splits for terms group bys for top_n', () => { + test('should return a splits for terms group bys for top_n', async () => { const resp = { aggregations: { SERIES: { @@ -84,7 +85,7 @@ describe('getSplits(resp, panel, series)', () => { ], }; const panel = { type: 'top_n' }; - expect(getSplits(resp, panel, series)).toEqual([ + expect(await getSplits(resp, panel, series)).toEqual([ { id: 'SERIES:example-01', key: 'example-01', @@ -92,6 +93,7 @@ describe('getSplits(resp, panel, series)', () => { labelFormatted: '', meta: { bucketSize: 10 }, color: 'rgb(255, 0, 0)', + splitByLabel: 'Overall Average of Average of cpu', timeseries: { buckets: [] }, SIBAGG: { value: 1 }, }, @@ -102,13 +104,14 @@ describe('getSplits(resp, panel, series)', () => { labelFormatted: '', meta: { bucketSize: 10 }, color: 'rgb(255, 0, 0)', + splitByLabel: 'Overall Average of Average of cpu', timeseries: { buckets: [] }, SIBAGG: { value: 2 }, }, ]); }); - test('should return a splits for terms group with label formatted by {{key}} placeholder', () => { + test('should return a splits for terms group with label formatted by {{key}} placeholder', async () => { const resp = { aggregations: { SERIES: { @@ -141,7 +144,7 @@ describe('getSplits(resp, panel, series)', () => { ], }; const panel = { type: 'top_n' }; - expect(getSplits(resp, panel, series)).toEqual([ + expect(await getSplits(resp, panel, series)).toEqual([ { id: 'SERIES:example-01', key: 'example-01', @@ -149,6 +152,7 @@ describe('getSplits(resp, panel, series)', () => { labelFormatted: '', meta: { bucketSize: 10 }, color: 'rgb(255, 0, 0)', + splitByLabel: 'Overall Average of Average of cpu', timeseries: { buckets: [] }, SIBAGG: { value: 1 }, }, @@ -159,13 +163,14 @@ describe('getSplits(resp, panel, series)', () => { labelFormatted: '', meta: { bucketSize: 10 }, color: 'rgb(255, 0, 0)', + splitByLabel: 'Overall Average of Average of cpu', timeseries: { buckets: [] }, SIBAGG: { value: 2 }, }, ]); }); - test('should return a splits for terms group with labelFormatted if {{key}} placeholder is applied and key_as_string exists', () => { + test('should return a splits for terms group with labelFormatted if {{key}} placeholder is applied and key_as_string exists', async () => { const resp = { aggregations: { SERIES: { @@ -200,7 +205,8 @@ describe('getSplits(resp, panel, series)', () => { ], }; const panel = { type: 'top_n' }; - expect(getSplits(resp, panel, series)).toEqual([ + + expect(await getSplits(resp, panel, series)).toEqual([ { id: 'SERIES:example-01', key: 'example-01', @@ -209,6 +215,7 @@ describe('getSplits(resp, panel, series)', () => { labelFormatted: '--false--', meta: { bucketSize: 10 }, color: 'rgb(255, 0, 0)', + splitByLabel: 'Overall Average of Average of cpu', timeseries: { buckets: [] }, SIBAGG: { value: 1 }, }, @@ -220,6 +227,7 @@ describe('getSplits(resp, panel, series)', () => { labelFormatted: '--true--', meta: { bucketSize: 10 }, color: 'rgb(255, 0, 0)', + splitByLabel: 'Overall Average of Average of cpu', timeseries: { buckets: [] }, SIBAGG: { value: 2 }, }, @@ -247,7 +255,7 @@ describe('getSplits(resp, panel, series)', () => { }, }; - test('should return a splits with no color', () => { + test('should return a splits with no color', async () => { const series = { id: 'SERIES', color: '#F00', @@ -260,7 +268,8 @@ describe('getSplits(resp, panel, series)', () => { ], }; const panel = { type: 'timeseries' }; - expect(getSplits(resp, panel, series)).toEqual([ + + expect(await getSplits(resp, panel, series)).toEqual([ { id: 'SERIES:example-01', key: 'example-01', @@ -268,6 +277,7 @@ describe('getSplits(resp, panel, series)', () => { labelFormatted: '', meta: { bucketSize: 10 }, color: undefined, + splitByLabel: 'Overall Average of Average of cpu', timeseries: { buckets: [] }, SIBAGG: { value: 1 }, }, @@ -278,13 +288,14 @@ describe('getSplits(resp, panel, series)', () => { labelFormatted: '', meta: { bucketSize: 10 }, color: undefined, + splitByLabel: 'Overall Average of Average of cpu', timeseries: { buckets: [] }, SIBAGG: { value: 2 }, }, ]); }); - test('should return gradient color', () => { + test('should return gradient color', async () => { const series = { id: 'SERIES', color: '#F00', @@ -298,7 +309,8 @@ describe('getSplits(resp, panel, series)', () => { ], }; const panel = { type: 'timeseries' }; - expect(getSplits(resp, panel, series)).toEqual([ + + expect(await getSplits(resp, panel, series)).toEqual([ expect.objectContaining({ color: 'rgb(255, 0, 0)', }), @@ -308,7 +320,7 @@ describe('getSplits(resp, panel, series)', () => { ]); }); - test('should return rainbow color', () => { + test('should return rainbow color', async () => { const series = { id: 'SERIES', color: '#F00', @@ -322,7 +334,8 @@ describe('getSplits(resp, panel, series)', () => { ], }; const panel = { type: 'timeseries' }; - expect(getSplits(resp, panel, series)).toEqual([ + + expect(await getSplits(resp, panel, series)).toEqual([ expect.objectContaining({ color: '#68BC00', }), @@ -333,7 +346,7 @@ describe('getSplits(resp, panel, series)', () => { }); }); - test('should return a splits for filters group bys', () => { + test('should return a splits for filters group bys', async () => { const resp = { aggregations: { SERIES: { @@ -360,7 +373,8 @@ describe('getSplits(resp, panel, series)', () => { metrics: [{ id: 'COUNT', type: 'count' }], }; const panel = { type: 'timeseries' }; - expect(getSplits(resp, panel, series)).toEqual([ + + expect(await getSplits(resp, panel, series)).toEqual([ { id: 'SERIES:filter-1', key: 'filter-1', diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/date_histogram.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/date_histogram.js index 617a75f6bd59f..f32bacac82dac 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/date_histogram.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/date_histogram.js @@ -20,7 +20,8 @@ import { overwrite } from '../../helpers'; import { getBucketSize } from '../../helpers/get_bucket_size'; import { getTimerange } from '../../helpers/get_timerange'; -import { search } from '../../../../../../../plugins/data/server'; +import { search, UI_SETTINGS } from '../../../../../../../plugins/data/server'; + const { dateHistogramInterval } = search.aggs; export function dateHistogram( @@ -30,9 +31,10 @@ export function dateHistogram( esQueryConfig, indexPatternObject, capabilities, - { barTargetUiSettings } + uiSettings ) { - return (next) => (doc) => { + return (next) => async (doc) => { + const barTargetUiSettings = await uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET); const timeField = annotation.time_field; const { bucketSize, intervalString } = getBucketSize( req, diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/query.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/query.js index cf02f601ea5ff..ec6f52ca30a9c 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/query.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/query.js @@ -19,7 +19,7 @@ import { getBucketSize } from '../../helpers/get_bucket_size'; import { getTimerange } from '../../helpers/get_timerange'; -import { esQuery } from '../../../../../../data/server'; +import { esQuery, UI_SETTINGS } from '../../../../../../data/server'; export function query( req, @@ -28,9 +28,10 @@ export function query( esQueryConfig, indexPattern, capabilities, - { barTargetUiSettings } + uiSettings ) { - return (next) => (doc) => { + return (next) => async (doc) => { + const barTargetUiSettings = await uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET); const timeField = annotation.time_field; const { bucketSize } = getBucketSize(req, 'auto', capabilities, barTargetUiSettings); const { from, to } = getTimerange(req); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/top_hits.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/top_hits.js index bdf2aac943b1b..2e1d9291d1c5f 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/top_hits.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/top_hits.js @@ -23,6 +23,7 @@ export function topHits(req, panel, annotation) { return (next) => (doc) => { const fields = (annotation.fields && annotation.fields.split(/[,\s]+/)) || []; const timeField = annotation.time_field; + overwrite(doc, `aggs.${annotation.id}.aggs.hits.top_hits`, { sort: [ { diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/date_histogram.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/date_histogram.js index 98c683bda1fdb..2133d39913180 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/date_histogram.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/date_histogram.js @@ -22,7 +22,7 @@ import { getBucketSize } from '../../helpers/get_bucket_size'; import { offsetTime } from '../../offset_time'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; import { isLastValueTimerangeMode } from '../../helpers/get_timerange_mode'; -import { search } from '../../../../../../../plugins/data/server'; +import { search, UI_SETTINGS } from '../../../../../../../plugins/data/server'; const { dateHistogramInterval } = search.aggs; export function dateHistogram( @@ -32,9 +32,12 @@ export function dateHistogram( esQueryConfig, indexPatternObject, capabilities, - { maxBarsUiSettings, barTargetUiSettings } + uiSettings ) { - return (next) => (doc) => { + return (next) => async (doc) => { + const maxBarsUiSettings = await uiSettings.get(UI_SETTINGS.HISTOGRAM_MAX_BARS); + const barTargetUiSettings = await uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET); + const { timeField, interval, maxBars } = getIntervalAndTimefield( panel, series, @@ -73,11 +76,10 @@ export function dateHistogram( ? getDateHistogramForLastBucketMode() : getDateHistogramForEntireTimerangeMode(); - // master - overwrite(doc, `aggs.${series.id}.meta`, { timeField, intervalString, + index: indexPatternObject?.title, bucketSize, seriesId: series.id, }); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/date_histogram.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/date_histogram.test.js index aa95a79a62796..05f2d5f39aa65 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/date_histogram.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/date_histogram.test.js @@ -19,6 +19,7 @@ import { DefaultSearchCapabilities } from '../../../search_strategies/default_search_capabilities'; import { dateHistogram } from './date_histogram'; +import { UI_SETTINGS } from '../../../../../../data/common'; describe('dateHistogram(req, panel, series)', () => { let panel; @@ -51,20 +52,30 @@ describe('dateHistogram(req, panel, series)', () => { }; indexPatternObject = {}; capabilities = new DefaultSearchCapabilities(req); - uiSettings = { maxBarsUiSettings: 100, barTargetUiSettings: 50 }; + uiSettings = { + get: async (key) => (key === UI_SETTINGS.HISTOGRAM_MAX_BARS ? 100 : 50), + }; }); - test('calls next when finished', () => { + test('calls next when finished', async () => { const next = jest.fn(); - dateHistogram(req, panel, series, config, indexPatternObject, capabilities, uiSettings)(next)( - {} - ); + + await dateHistogram( + req, + panel, + series, + config, + indexPatternObject, + capabilities, + uiSettings + )(next)({}); + expect(next.mock.calls.length).toEqual(1); }); - test('returns valid date histogram', () => { + test('returns valid date histogram', async () => { const next = (doc) => doc; - const doc = dateHistogram( + const doc = await dateHistogram( req, panel, series, @@ -102,10 +113,10 @@ describe('dateHistogram(req, panel, series)', () => { }); }); - test('returns valid date histogram (offset by 1h)', () => { + test('returns valid date histogram (offset by 1h)', async () => { series.offset_time = '1h'; const next = (doc) => doc; - const doc = dateHistogram( + const doc = await dateHistogram( req, panel, series, @@ -143,13 +154,13 @@ describe('dateHistogram(req, panel, series)', () => { }); }); - test('returns valid date histogram with overridden index pattern', () => { + test('returns valid date histogram with overridden index pattern', async () => { series.override_index_pattern = 1; series.series_index_pattern = '*'; series.series_time_field = 'timestamp'; series.series_interval = '20s'; const next = (doc) => doc; - const doc = dateHistogram( + const doc = await dateHistogram( req, panel, series, @@ -188,12 +199,12 @@ describe('dateHistogram(req, panel, series)', () => { }); describe('dateHistogram for entire time range mode', () => { - test('should ignore entire range mode for timeseries', () => { + test('should ignore entire range mode for timeseries', async () => { panel.time_range_mode = 'entire_time_range'; panel.type = 'timeseries'; const next = (doc) => doc; - const doc = dateHistogram( + const doc = await dateHistogram( req, panel, series, @@ -207,11 +218,11 @@ describe('dateHistogram(req, panel, series)', () => { expect(doc.aggs.test.aggs.timeseries.date_histogram).toBeDefined(); }); - test('should returns valid date histogram for entire range mode', () => { + test('should returns valid date histogram for entire range mode', async () => { panel.time_range_mode = 'entire_time_range'; const next = (doc) => doc; - const doc = dateHistogram( + const doc = await dateHistogram( req, panel, series, diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/filter_ratios.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/filter_ratios.js index 6c1699912f76f..9e05a7631a9f5 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/filter_ratios.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/filter_ratios.js @@ -17,11 +17,12 @@ * under the License. */ -const filter = (metric) => metric.type === 'filter_ratio'; import { bucketTransform } from '../../helpers/bucket_transform'; import { overwrite } from '../../helpers'; import { esQuery } from '../../../../../../data/server'; +const filter = (metric) => metric.type === 'filter_ratio'; + export function ratios(req, panel, series, esQueryConfig, indexPatternObject) { return (next) => (doc) => { if (series.metrics.some(filter)) { diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/metric_buckets.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/metric_buckets.js index 023ee054a5e13..7441ed0a274f2 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/metric_buckets.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/metric_buckets.js @@ -20,6 +20,7 @@ import { overwrite } from '../../helpers'; import { getBucketSize } from '../../helpers/get_bucket_size'; import { bucketTransform } from '../../helpers/bucket_transform'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; +import { UI_SETTINGS } from '../../../../../../data/common'; export function metricBuckets( req, @@ -28,9 +29,11 @@ export function metricBuckets( esQueryConfig, indexPatternObject, capabilities, - { barTargetUiSettings } + uiSettings ) { - return (next) => (doc) => { + return (next) => async (doc) => { + const barTargetUiSettings = await uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET); + const { interval } = getIntervalAndTimefield(panel, series, indexPatternObject); const { intervalString } = getBucketSize(req, interval, capabilities, barTargetUiSettings); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/metric_buckets.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/metric_buckets.test.js index 2154d2257815b..1789517c0f332 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/metric_buckets.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/metric_buckets.test.js @@ -63,20 +63,20 @@ describe('metricBuckets(req, panel, series)', () => { {}, undefined, { - barTargetUiSettings: 50, + get: async () => 50, } ); }); - test('calls next when finished', () => { + test('calls next when finished', async () => { const next = jest.fn(); - metricBucketsProcessor(next)({}); + await metricBucketsProcessor(next)({}); expect(next.mock.calls.length).toEqual(1); }); - test('returns metric aggs', () => { + test('returns metric aggs', async () => { const next = (doc) => doc; - const doc = metricBucketsProcessor(next)({}); + const doc = await metricBucketsProcessor(next)({}); expect(doc).toEqual({ aggs: { diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/positive_rate.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/positive_rate.js index c16e0fd3aaf15..8e18ba725b003 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/positive_rate.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/positive_rate.js @@ -21,6 +21,7 @@ import { getBucketSize } from '../../helpers/get_bucket_size'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; import { bucketTransform } from '../../helpers/bucket_transform'; import { overwrite } from '../../helpers'; +import { UI_SETTINGS } from '../../../../../../data/common'; export const filter = (metric) => metric.type === 'positive_rate'; @@ -29,7 +30,11 @@ export const createPositiveRate = (doc, intervalString, aggRoot) => (metric) => const derivativeFn = bucketTransform.derivative; const positiveOnlyFn = bucketTransform.positive_only; - const maxMetric = { id: `${metric.id}-positive-rate-max`, type: 'max', field: metric.field }; + const maxMetric = { + id: `${metric.id}-positive-rate-max`, + type: 'max', + field: metric.field, + }; const derivativeMetric = { id: `${metric.id}-positive-rate-derivative`, type: 'derivative', @@ -64,9 +69,11 @@ export function positiveRate( esQueryConfig, indexPatternObject, capabilities, - { barTargetUiSettings } + uiSettings ) { - return (next) => (doc) => { + return (next) => async (doc) => { + const barTargetUiSettings = await uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET); + const { interval } = getIntervalAndTimefield(panel, series, indexPatternObject); const { intervalString } = getBucketSize(req, interval, capabilities, barTargetUiSettings); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/positive_rate.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/positive_rate.test.js index d891fc01bb266..acec4b466f397 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/positive_rate.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/positive_rate.test.js @@ -51,19 +51,21 @@ describe('positiveRate(req, panel, series)', () => { }, }; uiSettings = { - barTargetUiSettings: 50, + get: async () => 50, }; }); - test('calls next when finished', () => { + test('calls next when finished', async () => { const next = jest.fn(); - positiveRate(req, panel, series, {}, {}, undefined, uiSettings)(next)({}); + await positiveRate(req, panel, series, {}, {}, undefined, uiSettings)(next)({}); + expect(next.mock.calls.length).toEqual(1); }); - test('returns positive rate aggs', () => { + test('returns positive rate aggs', async () => { const next = (doc) => doc; - const doc = positiveRate(req, panel, series, {}, {}, undefined, uiSettings)(next)({}); + const doc = await positiveRate(req, panel, series, {}, {}, undefined, uiSettings)(next)({}); + expect(doc).toEqual({ aggs: { test: { diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/sibling_buckets.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/sibling_buckets.js index f69473b613d1b..b17d63c10877a 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/sibling_buckets.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/sibling_buckets.js @@ -21,6 +21,7 @@ import { overwrite } from '../../helpers'; import { getBucketSize } from '../../helpers/get_bucket_size'; import { bucketTransform } from '../../helpers/bucket_transform'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; +import { UI_SETTINGS } from '../../../../../../data/common'; export function siblingBuckets( req, @@ -29,9 +30,10 @@ export function siblingBuckets( esQueryConfig, indexPatternObject, capabilities, - { barTargetUiSettings } + uiSettings ) { - return (next) => (doc) => { + return (next) => async (doc) => { + const barTargetUiSettings = await uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET); const { interval } = getIntervalAndTimefield(panel, series, indexPatternObject); const { bucketSize } = getBucketSize(req, interval, capabilities, barTargetUiSettings); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/sibling_buckets.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/sibling_buckets.test.js index 48714e83341ea..367b6fa242b72 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/sibling_buckets.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/sibling_buckets.test.js @@ -56,19 +56,19 @@ describe('siblingBuckets(req, panel, series)', () => { }, }; uiSettings = { - barTargetUiSettings: 50, + get: async () => 50, }; }); - test('calls next when finished', () => { + test('calls next when finished', async () => { const next = jest.fn(); - siblingBuckets(req, panel, series, {}, {}, undefined, uiSettings)(next)({}); + await siblingBuckets(req, panel, series, {}, {}, undefined, uiSettings)(next)({}); expect(next.mock.calls.length).toEqual(1); }); - test('returns sibling aggs', () => { + test('returns sibling aggs', async () => { const next = (doc) => doc; - const doc = siblingBuckets(req, panel, series, {}, {}, undefined, uiSettings)(next)({}); + const doc = await siblingBuckets(req, panel, series, {}, {}, undefined, uiSettings)(next)({}); expect(doc).toEqual({ aggs: { diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_terms.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_terms.js index 240a5d76b7c6a..6a8006f2f5fea 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_terms.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_terms.js @@ -25,9 +25,12 @@ import { bucketTransform } from '../../helpers/bucket_transform'; export function splitByTerms(req, panel, series) { return (next) => (doc) => { if (series.split_mode === 'terms' && series.terms_field) { + const termsField = series.terms_field; + const orderByTerms = series.terms_order_by; + const direction = series.terms_direction || 'desc'; - const metric = series.metrics.find((item) => item.id === series.terms_order_by); - overwrite(doc, `aggs.${series.id}.terms.field`, series.terms_field); + const metric = series.metrics.find((item) => item.id === orderByTerms); + overwrite(doc, `aggs.${series.id}.terms.field`, termsField); overwrite(doc, `aggs.${series.id}.terms.size`, series.terms_size); if (series.terms_include) { overwrite(doc, `aggs.${series.id}.terms.include`, series.terms_include); @@ -36,16 +39,16 @@ export function splitByTerms(req, panel, series) { overwrite(doc, `aggs.${series.id}.terms.exclude`, series.terms_exclude); } if (metric && metric.type !== 'count' && ~basicAggs.indexOf(metric.type)) { - const sortAggKey = `${series.terms_order_by}-SORT`; + const sortAggKey = `${orderByTerms}-SORT`; const fn = bucketTransform[metric.type]; - const bucketPath = getBucketsPath(series.terms_order_by, series.metrics).replace( - series.terms_order_by, + const bucketPath = getBucketsPath(orderByTerms, series.metrics).replace( + orderByTerms, sortAggKey ); overwrite(doc, `aggs.${series.id}.terms.order`, { [bucketPath]: direction }); overwrite(doc, `aggs.${series.id}.aggs`, { [sortAggKey]: fn(metric) }); - } else if (['_key', '_count'].includes(series.terms_order_by)) { - overwrite(doc, `aggs.${series.id}.terms.order`, { [series.terms_order_by]: direction }); + } else if (['_key', '_count'].includes(orderByTerms)) { + overwrite(doc, `aggs.${series.id}.terms.order`, { [orderByTerms]: direction }); } else { overwrite(doc, `aggs.${series.id}.terms.order`, { _count: direction }); } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/date_histogram.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/date_histogram.js index ba65e583cc094..7dfc0cec74d12 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/date_histogram.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/date_histogram.js @@ -23,7 +23,7 @@ import { isLastValueTimerangeMode } from '../../helpers/get_timerange_mode'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; import { getTimerange } from '../../helpers/get_timerange'; import { calculateAggRoot } from './calculate_agg_root'; -import { search } from '../../../../../../../plugins/data/server'; +import { search, UI_SETTINGS } from '../../../../../../../plugins/data/server'; const { dateHistogramInterval } = search.aggs; export function dateHistogram( @@ -32,12 +32,14 @@ export function dateHistogram( esQueryConfig, indexPatternObject, capabilities, - { barTargetUiSettings } + uiSettings ) { - return (next) => (doc) => { + return (next) => async (doc) => { + const barTargetUiSettings = await uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET); const { timeField, interval } = getIntervalAndTimefield(panel, {}, indexPatternObject); const meta = { timeField, + index: indexPatternObject?.title, }; const getDateHistogramForLastBucketMode = () => { @@ -65,7 +67,7 @@ export function dateHistogram( }); overwrite(doc, aggRoot.replace(/\.aggs$/, '.meta'), { - timeField, + ...meta, intervalString, bucketSize, }); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/filter_ratios.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/filter_ratios.js index 13874166bc558..0166537146e0b 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/filter_ratios.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/filter_ratios.js @@ -17,12 +17,13 @@ * under the License. */ -const filter = (metric) => metric.type === 'filter_ratio'; import { esQuery } from '../../../../../../data/server'; import { bucketTransform } from '../../helpers/bucket_transform'; import { overwrite } from '../../helpers'; import { calculateAggRoot } from './calculate_agg_root'; +const filter = (metric) => metric.type === 'filter_ratio'; + export function ratios(req, panel, esQueryConfig, indexPatternObject) { return (next) => (doc) => { panel.series.forEach((column) => { diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/metric_buckets.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/metric_buckets.js index fe6a8b537d64b..c5501233f8135 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/metric_buckets.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/metric_buckets.js @@ -22,6 +22,7 @@ import { getBucketSize } from '../../helpers/get_bucket_size'; import { bucketTransform } from '../../helpers/bucket_transform'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; import { calculateAggRoot } from './calculate_agg_root'; +import { UI_SETTINGS } from '../../../../../../data/common'; export function metricBuckets( req, @@ -29,9 +30,10 @@ export function metricBuckets( esQueryConfig, indexPatternObject, capabilities, - { barTargetUiSettings } + uiSettings ) { - return (next) => (doc) => { + return (next) => async (doc) => { + const barTargetUiSettings = await uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET); const { interval } = getIntervalAndTimefield(panel, {}, indexPatternObject); const { intervalString } = getBucketSize(req, interval, capabilities, barTargetUiSettings); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/pivot.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/pivot.js index ad085f25cf451..8ae50f62ca210 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/pivot.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/pivot.js @@ -27,6 +27,7 @@ import { bucketTransform } from '../../helpers/bucket_transform'; export function pivot(req, panel) { return (next) => (doc) => { const { sort } = req.payload.state; + if (panel.pivot_id) { overwrite(doc, 'aggs.pivot.terms.field', panel.pivot_id); overwrite(doc, 'aggs.pivot.terms.size', panel.pivot_rows); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/positive_rate.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/positive_rate.js index 6cf165d124e26..914b246bc8fdf 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/positive_rate.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/positive_rate.js @@ -21,6 +21,7 @@ import { getBucketSize } from '../../helpers/get_bucket_size'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; import { calculateAggRoot } from './calculate_agg_root'; import { createPositiveRate, filter } from '../series/positive_rate'; +import { UI_SETTINGS } from '../../../../../../data/common'; export function positiveRate( req, @@ -28,9 +29,10 @@ export function positiveRate( esQueryConfig, indexPatternObject, capabilities, - { barTargetUiSettings } + uiSettings ) { - return (next) => (doc) => { + return (next) => async (doc) => { + const barTargetUiSettings = await uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET); const { interval } = getIntervalAndTimefield(panel, {}, indexPatternObject); const { intervalString } = getBucketSize(req, interval, capabilities, barTargetUiSettings); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/sibling_buckets.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/sibling_buckets.js index ba08b18256dec..1333cecc36a92 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/sibling_buckets.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/sibling_buckets.js @@ -22,6 +22,7 @@ import { getBucketSize } from '../../helpers/get_bucket_size'; import { bucketTransform } from '../../helpers/bucket_transform'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; import { calculateAggRoot } from './calculate_agg_root'; +import { UI_SETTINGS } from '../../../../../../data/common'; export function siblingBuckets( req, @@ -29,9 +30,10 @@ export function siblingBuckets( esQueryConfig, indexPatternObject, capabilities, - { barTargetUiSettings } + uiSettings ) { - return (next) => (doc) => { + return (next) => async (doc) => { + const barTargetUiSettings = await uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET); const { interval } = getIntervalAndTimefield(panel, {}, indexPatternObject); const { bucketSize } = getBucketSize(req, interval, capabilities, barTargetUiSettings); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/math.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/math.js index f8752ce8fa3a8..2e4c05273ee3f 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/math.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/math.js @@ -25,8 +25,8 @@ import { getSplits } from '../../helpers/get_splits'; import { mapBucket } from '../../helpers/map_bucket'; import { evaluate } from 'tinymath'; -export function mathAgg(resp, panel, series, meta) { - return (next) => (results) => { +export function mathAgg(resp, panel, series, meta, extractFields) { + return (next) => async (results) => { const mathMetric = last(series.metrics); if (mathMetric.type !== 'math') return next(results); // Filter the results down to only the ones that match the series.id. Sometimes @@ -38,7 +38,7 @@ export function mathAgg(resp, panel, series, meta) { return true; }); const decoration = getDefaultDecoration(series); - const splits = getSplits(resp, panel, series, meta); + const splits = await getSplits(resp, panel, series, meta, extractFields); const mathSeries = splits.map((split) => { if (mathMetric.variables.length) { // Gather the data for the splits. The data will either be a sibling agg or diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/math.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/math.test.js index 79cfd2ddd54bb..c65571379d50a 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/math.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/math.test.js @@ -91,15 +91,16 @@ describe('math(resp, panel, series)', () => { }; }); - test('calls next when finished', () => { + test('calls next when finished', async () => { const next = jest.fn(); - mathAgg(resp, panel, series)(next)([]); + await mathAgg(resp, panel, series)(next)([]); expect(next.mock.calls.length).toEqual(1); }); - test('creates a series', () => { - const next = mathAgg(resp, panel, series)((results) => results); - const results = stdMetric(resp, panel, series)(next)([]); + test('creates a series', async () => { + const next = await mathAgg(resp, panel, series)((results) => results); + const results = await stdMetric(resp, panel, series)(next)([]); + expect(results).toHaveLength(1); expect(results[0]).toEqual({ @@ -118,12 +119,12 @@ describe('math(resp, panel, series)', () => { }); }); - test('turns division by zero into null values', () => { + test('turns division by zero into null values', async () => { resp.aggregations.test.buckets[0].timeseries.buckets[0].mincpu = 0; - const next = mathAgg(resp, panel, series)((results) => results); - const results = stdMetric(resp, panel, series)(next)([]); - expect(results).toHaveLength(1); + const next = await mathAgg(resp, panel, series)((results) => results); + const results = await stdMetric(resp, panel, series)(next)([]); + expect(results).toHaveLength(1); expect(results[0]).toEqual( expect.objectContaining({ data: [ @@ -134,15 +135,35 @@ describe('math(resp, panel, series)', () => { ); }); - test('throws on actual tinymath expression errors', () => { + test('throws on actual tinymath expression errors #1', async () => { series.metrics[2].script = 'notExistingFn(params.a)'; - expect(() => - stdMetric(resp, panel, series)(mathAgg(resp, panel, series)((results) => results))([]) - ).toThrow(); + try { + await stdMetric( + resp, + panel, + series + )(await mathAgg(resp, panel, series)((results) => results))([]); + } catch (e) { + expect(e.message).toEqual( + 'Failed to parse expression. Expected "*", "+", "-", "/", or end of input but "(" found.' + ); + } + }); + + test('throws on actual tinymath expression errors #2', async () => { series.metrics[2].script = 'divide(params.a, params.b'; - expect(() => - stdMetric(resp, panel, series)(mathAgg(resp, panel, series)((results) => results))([]) - ).toThrow(); + + try { + await stdMetric( + resp, + panel, + series + )(await mathAgg(resp, panel, series)((results) => results))([]); + } catch (e) { + expect(e.message).toEqual( + 'Failed to parse expression. Expected "*", "+", "-", "/", or end of input but "(" found.' + ); + } }); }); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.js index 2e0d176f80b23..6703202ef6b49 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.js @@ -23,15 +23,15 @@ import { getSplits } from '../../helpers/get_splits'; import { getLastMetric } from '../../helpers/get_last_metric'; import { METRIC_TYPES } from '../../../../../common/metric_types'; -export function percentile(resp, panel, series, meta) { - return (next) => (results) => { +export function percentile(resp, panel, series, meta, extractFields) { + return (next) => async (results) => { const metric = getLastMetric(series); if (metric.type !== METRIC_TYPES.PERCENTILE) { return next(results); } - getSplits(resp, panel, series, meta).forEach((split) => { + (await getSplits(resp, panel, series, meta, extractFields)).forEach((split) => { metric.percentiles.forEach((percentile) => { const percentileValue = percentile.value ? percentile.value : 0; const id = `${split.id}:${percentile.id}`; diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.test.js index d239cb2138fe1..225cc5e261a3a 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile.test.js @@ -80,15 +80,18 @@ describe('percentile(resp, panel, series)', () => { }; }); - test('calls next when finished', () => { + test('calls next when finished', async () => { const next = jest.fn(); - percentile(resp, panel, series)(next)([]); + + await percentile(resp, panel, series, {})(next)([]); + expect(next.mock.calls.length).toEqual(1); }); - test('creates a series', () => { + test('creates a series', async () => { const next = (results) => results; - const results = percentile(resp, panel, series)(next)([]); + const results = await percentile(resp, panel, series, {})(next)([]); + expect(results).toHaveLength(2); expect(results[0]).toHaveProperty('id', 'test:10-90'); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile_rank.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile_rank.js index c163605af7ac5..7660dd80d143d 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile_rank.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/percentile_rank.js @@ -23,15 +23,15 @@ import { getLastMetric } from '../../helpers/get_last_metric'; import { toPercentileNumber } from '../../../../../common/to_percentile_number'; import { METRIC_TYPES } from '../../../../../common/metric_types'; -export function percentileRank(resp, panel, series, meta) { - return (next) => (results) => { +export function percentileRank(resp, panel, series, meta, extractFields) { + return (next) => async (results) => { const metric = getLastMetric(series); if (metric.type !== METRIC_TYPES.PERCENTILE_RANK) { return next(results); } - getSplits(resp, panel, series, meta).forEach((split) => { + (await getSplits(resp, panel, series, meta, extractFields)).forEach((split) => { (metric.values || []).forEach((percentileRank, index) => { const data = split.timeseries.buckets.map((bucket) => [ bucket.key, diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/series_agg.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/series_agg.js index d2b0ce9226bb9..07aebea78a1fb 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/series_agg.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/series_agg.js @@ -22,8 +22,8 @@ import _ from 'lodash'; import { getDefaultDecoration } from '../../helpers/get_default_decoration'; import { calculateLabel } from '../../../../../common/calculate_label'; -export function seriesAgg(resp, panel, series) { - return (next) => (results) => { +export function seriesAgg(resp, panel, series, meta, extractFields) { + return (next) => async (results) => { if (series.metrics.some((m) => m.type === 'series_agg')) { const decoration = getDefaultDecoration(series); @@ -43,9 +43,14 @@ export function seriesAgg(resp, panel, series) { const fn = SeriesAgg[m.function]; return (fn && fn(acc)) || acc; }, targetSeries); + + const fieldsForMetaIndex = meta.index ? await extractFields(meta.index) : []; + results.push({ id: `${series.id}`, - label: series.label || calculateLabel(_.last(series.metrics), series.metrics), + label: + series.label || + calculateLabel(_.last(series.metrics), series.metrics, fieldsForMetaIndex), color: series.color, data: _.first(data), ...decoration, diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/series_agg.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/series_agg.test.js index b458eee17bce5..ddf4f620f0657 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/series_agg.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/series_agg.test.js @@ -91,15 +91,16 @@ describe('seriesAgg(resp, panel, series)', () => { }; }); - test('calls next when finished', () => { + test('calls next when finished', async () => { const next = jest.fn(); - seriesAgg(resp, panel, series)(next)([]); + await seriesAgg(resp, panel, series, {})(next)([]); expect(next.mock.calls.length).toEqual(1); }); - test('creates a series', () => { - const next = seriesAgg(resp, panel, series)((results) => results); - const results = stdMetric(resp, panel, series)(next)([]); + test('creates a series', async () => { + const next = await seriesAgg(resp, panel, series, {})((results) => results); + const results = await stdMetric(resp, panel, series, {})(next)([]); + expect(results).toHaveLength(1); expect(results[0]).toEqual({ diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_bands.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_bands.js index be95913c6ec38..ffc3d2636d1af 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_bands.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_bands.js @@ -20,36 +20,38 @@ import { getAggValue, getLastMetric, getSplits } from '../../helpers'; import { METRIC_TYPES } from '../../../../../common/metric_types'; -export function stdDeviationBands(resp, panel, series, meta) { - return (next) => (results) => { +export function stdDeviationBands(resp, panel, series, meta, extractFields) { + return (next) => async (results) => { const metric = getLastMetric(series); if (metric.type === METRIC_TYPES.STD_DEVIATION && metric.mode === 'band') { - getSplits(resp, panel, series, meta).forEach(({ id, color, label, timeseries }) => { - const data = timeseries.buckets.map((bucket) => [ - bucket.key, - getAggValue(bucket, { ...metric, mode: 'upper' }), - getAggValue(bucket, { ...metric, mode: 'lower' }), - ]); + (await getSplits(resp, panel, series, meta, extractFields)).forEach( + ({ id, color, label, timeseries }) => { + const data = timeseries.buckets.map((bucket) => [ + bucket.key, + getAggValue(bucket, { ...metric, mode: 'upper' }), + getAggValue(bucket, { ...metric, mode: 'lower' }), + ]); - results.push({ - id, - label, - color, - data, - lines: { - show: series.chart_type === 'line', - fill: 0.5, - lineWidth: 0, - mode: 'band', - }, - bars: { - show: series.chart_type === 'bar', - fill: 0.5, - mode: 'band', - }, - points: { show: false }, - }); - }); + results.push({ + id, + label, + color, + data, + lines: { + show: series.chart_type === 'line', + fill: 0.5, + lineWidth: 0, + mode: 'band', + }, + bars: { + show: series.chart_type === 'bar', + fill: 0.5, + mode: 'band', + }, + points: { show: false }, + }); + } + ); } return next(results); }; diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_bands.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_bands.test.js index 4899eaed2611a..97d0cc8a84f72 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_bands.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_bands.test.js @@ -77,15 +77,15 @@ describe('stdDeviationBands(resp, panel, series)', () => { }; }); - test('calls next when finished', () => { + test('calls next when finished', async () => { const next = jest.fn(); - stdDeviationBands(resp, panel, series)(next)([]); + await stdDeviationBands(resp, panel, series, {})(next)([]); expect(next.mock.calls.length).toEqual(1); }); - test('creates a series', () => { + test('creates a series', async () => { const next = (results) => results; - const results = stdDeviationBands(resp, panel, series)(next)([]); + const results = await stdDeviationBands(resp, panel, series, {})(next)([]); expect(results).toHaveLength(1); expect(results[0]).toEqual({ diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_sibling.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_sibling.js index 321e1c5125e1c..652cd2feb979a 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_sibling.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_sibling.js @@ -19,11 +19,11 @@ import { getSplits, getLastMetric, getSiblingAggValue } from '../../helpers'; -export function stdDeviationSibling(resp, panel, series, meta) { - return (next) => (results) => { +export function stdDeviationSibling(resp, panel, series, meta, extractFields) { + return (next) => async (results) => { const metric = getLastMetric(series); if (metric.mode === 'band' && metric.type === 'std_deviation_bucket') { - getSplits(resp, panel, series, meta).forEach((split) => { + (await getSplits(resp, panel, series, meta, extractFields)).forEach((split) => { const data = split.timeseries.buckets.map((bucket) => [ bucket.key, getSiblingAggValue(split, { ...metric, mode: 'upper' }), diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_sibling.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_sibling.test.js index b6acf822bc242..93386a008ae96 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_sibling.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_deviation_sibling.test.js @@ -77,15 +77,15 @@ describe('stdDeviationSibling(resp, panel, series)', () => { }; }); - test('calls next when finished', () => { + test('calls next when finished', async () => { const next = jest.fn(); - stdDeviationSibling(resp, panel, series)(next)([]); + await stdDeviationSibling(resp, panel, series, {})(next)([]); expect(next.mock.calls.length).toEqual(1); }); - test('creates a series', () => { + test('creates a series', async () => { const next = (results) => results; - const results = stdDeviationSibling(resp, panel, series)(next)([]); + const results = await stdDeviationSibling(resp, panel, series, {})(next)([]); expect(results).toHaveLength(1); expect(results[0]).toEqual({ diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_metric.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_metric.js index e04c3a93e81bb..9b9dacd1af957 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_metric.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_metric.js @@ -23,8 +23,8 @@ import { getLastMetric } from '../../helpers/get_last_metric'; import { mapBucket } from '../../helpers/map_bucket'; import { METRIC_TYPES } from '../../../../../common/metric_types'; -export function stdMetric(resp, panel, series, meta) { - return (next) => (results) => { +export function stdMetric(resp, panel, series, meta, extractFields) { + return (next) => async (results) => { const metric = getLastMetric(series); if (metric.type === METRIC_TYPES.STD_DEVIATION && metric.mode === 'band') { return next(results); @@ -35,17 +35,20 @@ export function stdMetric(resp, panel, series, meta) { } if (/_bucket$/.test(metric.type)) return next(results); const decoration = getDefaultDecoration(series); - getSplits(resp, panel, series, meta).forEach((split) => { + + (await getSplits(resp, panel, series, meta, extractFields)).forEach((split) => { const data = split.timeseries.buckets.map(mapBucket(metric)); results.push({ id: `${split.id}`, label: split.label, + splitByLabel: split.splitByLabel, labelFormatted: split.labelFormatted, color: split.color, data, ...decoration, }); }); + return next(results); }; } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_metric.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_metric.test.js index 78a29c04732d7..07590ba359bfe 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_metric.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_metric.test.js @@ -58,32 +58,38 @@ describe('stdMetric(resp, panel, series)', () => { }; }); - test('calls next when finished', () => { + test('calls next when finished', async () => { const next = jest.fn(); - stdMetric(resp, panel, series)(next)([]); + await stdMetric(resp, panel, series, {})(next)([]); + expect(next.mock.calls.length).toEqual(1); }); - test('calls next when finished (percentile)', () => { + test('calls next when finished (percentile)', async () => { series.metrics[0].type = 'percentile'; + const next = jest.fn((d) => d); - const results = stdMetric(resp, panel, series)(next)([]); + const results = await stdMetric(resp, panel, series, {})(next)([]); + expect(next.mock.calls.length).toEqual(1); expect(results).toHaveLength(0); }); - test('calls next when finished (std_deviation band)', () => { + test('calls next when finished (std_deviation band)', async () => { series.metrics[0].type = 'std_deviation'; series.metrics[0].mode = 'band'; + const next = jest.fn((d) => d); - const results = stdMetric(resp, panel, series)(next)([]); + const results = await stdMetric(resp, panel, series, {})(next)([]); + expect(next.mock.calls.length).toEqual(1); expect(results).toHaveLength(0); }); - test('creates a series', () => { + test('creates a series', async () => { const next = (results) => results; - const results = stdMetric(resp, panel, series)(next)([]); + const results = await stdMetric(resp, panel, series, {})(next)([]); + expect(results).toHaveLength(1); expect(results[0]).toHaveProperty('color', 'rgb(255, 0, 0)'); expect(results[0]).toHaveProperty('id', 'test'); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_sibling.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_sibling.js index b5d972a38769e..80f1f6c404724 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_sibling.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_sibling.js @@ -22,15 +22,15 @@ import { getSplits } from '../../helpers/get_splits'; import { getLastMetric } from '../../helpers/get_last_metric'; import { getSiblingAggValue } from '../../helpers/get_sibling_agg_value'; -export function stdSibling(resp, panel, series, meta) { - return (next) => (results) => { +export function stdSibling(resp, panel, series, meta, extractFields) { + return (next) => async (results) => { const metric = getLastMetric(series); if (!/_bucket$/.test(metric.type)) return next(results); if (metric.type === 'std_deviation_bucket' && metric.mode === 'band') return next(results); const decoration = getDefaultDecoration(series); - getSplits(resp, panel, series, meta).forEach((split) => { + (await getSplits(resp, panel, series, meta, extractFields)).forEach((split) => { const data = split.timeseries.buckets.map((bucket) => { return [bucket.key, getSiblingAggValue(split, metric)]; }); @@ -42,6 +42,7 @@ export function stdSibling(resp, panel, series, meta) { ...decoration, }); }); + return next(results); }; } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_sibling.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_sibling.test.js index d99ae6771c437..52edb8408b5bd 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_sibling.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_sibling.test.js @@ -72,23 +72,23 @@ describe('stdSibling(resp, panel, series)', () => { }; }); - test('calls next when finished', () => { + test('calls next when finished', async () => { const next = jest.fn(); - stdSibling(resp, panel, series)(next)([]); + await stdSibling(resp, panel, series, {})(next)([]); expect(next.mock.calls.length).toEqual(1); }); - test('calls next when std. deviation bands set', () => { + test('calls next when std. deviation bands set', async () => { series.metrics[1].mode = 'band'; const next = jest.fn((results) => results); - const results = stdSibling(resp, panel, series)(next)([]); + const results = await stdSibling(resp, panel, series, {})(next)([]); expect(next.mock.calls.length).toEqual(1); expect(results).toHaveLength(0); }); - test('creates a series', () => { + test('creates a series', async () => { const next = (results) => results; - const results = stdSibling(resp, panel, series)(next)([]); + const results = await stdSibling(resp, panel, series, {})(next)([]); expect(results).toHaveLength(1); expect(results[0]).toEqual({ diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/time_shift.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/time_shift.test.js index 57c1a8aead7dc..019d5d32c1c30 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/time_shift.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/time_shift.test.js @@ -60,15 +60,17 @@ describe('timeShift(resp, panel, series)', () => { }; }); - test('calls next when finished', () => { + test('calls next when finished', async () => { const next = jest.fn(); - timeShift(resp, panel, series)(next)([]); + await timeShift(resp, panel, series, {})(next)([]); + expect(next.mock.calls.length).toEqual(1); }); - test('creates a series', () => { - const next = timeShift(resp, panel, series)((results) => results); - const results = stdMetric(resp, panel, series)(next)([]); + test('creates a series', async () => { + const next = await timeShift(resp, panel, series, {})((results) => results); + const results = await stdMetric(resp, panel, series, {})(next)([]); + expect(results).toHaveLength(1); expect(results[0]).toHaveProperty('color', 'rgb(255, 0, 0)'); expect(results[0]).toHaveProperty('id', 'test'); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/index.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/index.js index cbd775bcd816b..ee4161288673c 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/index.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/index.js @@ -17,7 +17,6 @@ * under the License. */ -// import percentile from './percentile'; import { stdMetric } from './std_metric'; import { stdSibling } from './std_sibling'; import { seriesAgg } from './series_agg'; diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/percentile.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/percentile.js index 788bb6f14a0c7..33af66855ef3b 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/percentile.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/percentile.js @@ -22,8 +22,8 @@ import { getLastMetric } from '../../helpers/get_last_metric'; import { toPercentileNumber } from '../../../../../common/to_percentile_number'; import { METRIC_TYPES } from '../../../../../common/metric_types'; -export function percentile(bucket, panel, series) { - return (next) => (results) => { +export function percentile(bucket, panel, series, meta, extractFields) { + return (next) => async (results) => { const metric = getLastMetric(series); if (metric.type !== METRIC_TYPES.PERCENTILE) { @@ -34,7 +34,7 @@ export function percentile(bucket, panel, series) { aggregations: bucket, }; - getSplits(fakeResp, panel, series).forEach((split) => { + (await getSplits(fakeResp, panel, series, meta, extractFields)).forEach((split) => { // table allows only one percentile in a series (the last one will be chosen in case of several) const percentile = last(metric.percentiles); const percentileKey = toPercentileNumber(percentile.value); @@ -45,6 +45,7 @@ export function percentile(bucket, panel, series) { results.push({ id: split.id, + label: `${split.label} (${percentile.value ?? 0})`, data, }); }); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/percentile_rank.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/percentile_rank.js index c280538c7ce5f..c902631aaf47b 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/percentile_rank.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/percentile_rank.js @@ -23,8 +23,8 @@ import { toPercentileNumber } from '../../../../../common/to_percentile_number'; import { getAggValue } from '../../helpers/get_agg_value'; import { METRIC_TYPES } from '../../../../../common/metric_types'; -export function percentileRank(bucket, panel, series) { - return (next) => (results) => { +export function percentileRank(bucket, panel, series, meta, extractFields) { + return (next) => async (results) => { const metric = getLastMetric(series); if (metric.type !== METRIC_TYPES.PERCENTILE_RANK) { @@ -35,7 +35,7 @@ export function percentileRank(bucket, panel, series) { aggregations: bucket, }; - getSplits(fakeResp, panel, series).forEach((split) => { + (await getSplits(fakeResp, panel, series, meta, extractFields)).forEach((split) => { // table allows only one percentile rank in a series (the last one will be chosen in case of several) const lastRankValue = last(metric.values); const percentileRank = toPercentileNumber(lastRankValue); @@ -51,7 +51,7 @@ export function percentileRank(bucket, panel, series) { results.push({ data, id: split.id, - label: `${split.label} (${percentileRank || 0})`, + label: `${split.label} (${lastRankValue ?? 0})`, }); }); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/series_agg.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/series_agg.js index 343198bc22a6e..56a3207cd115a 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/series_agg.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/series_agg.js @@ -21,8 +21,8 @@ import { SeriesAgg } from './_series_agg'; import _ from 'lodash'; import { calculateLabel } from '../../../../../common/calculate_label'; -export function seriesAgg(resp, panel, series) { - return (next) => (results) => { +export function seriesAgg(resp, panel, series, meta, extractFields) { + return (next) => async (results) => { if (series.aggregate_by && series.aggregate_function) { const targetSeries = []; // Filter out the seires with the matching metric and store them @@ -36,9 +36,14 @@ export function seriesAgg(resp, panel, series) { }); const fn = SeriesAgg[series.aggregate_function]; const data = fn(targetSeries); + + const fieldsForMetaIndex = meta.index ? await extractFields(meta.index) : []; + results.push({ id: `${series.id}`, - label: series.label || calculateLabel(_.last(series.metrics), series.metrics), + label: + series.label || + calculateLabel(_.last(series.metrics), series.metrics, fieldsForMetaIndex), data: _.first(data), }); } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/std_metric.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/std_metric.js index 2242b338e7b92..6f7e8b0edd10d 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/std_metric.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/std_metric.js @@ -22,8 +22,8 @@ import { getLastMetric } from '../../helpers/get_last_metric'; import { mapBucket } from '../../helpers/map_bucket'; import { METRIC_TYPES } from '../../../../../common/metric_types'; -export function stdMetric(bucket, panel, series) { - return (next) => (results) => { +export function stdMetric(bucket, panel, series, meta, extractFields) { + return (next) => async (results) => { const metric = getLastMetric(series); if (metric.type === METRIC_TYPES.STD_DEVIATION && metric.mode === 'band') { @@ -42,7 +42,7 @@ export function stdMetric(bucket, panel, series) { aggregations: bucket, }; - getSplits(fakeResp, panel, series).forEach((split) => { + (await getSplits(fakeResp, panel, series, meta, extractFields)).forEach((split) => { const data = split.timeseries.buckets.map(mapBucket(metric)); results.push({ id: split.id, diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/std_sibling.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/std_sibling.js index 17cfac6e8895b..001da9019f116 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/std_sibling.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/std_sibling.js @@ -21,15 +21,15 @@ import { getSplits } from '../../helpers/get_splits'; import { getLastMetric } from '../../helpers/get_last_metric'; import { getSiblingAggValue } from '../../helpers/get_sibling_agg_value'; -export function stdSibling(bucket, panel, series) { - return (next) => (results) => { +export function stdSibling(bucket, panel, series, meta, extractFields) { + return (next) => async (results) => { const metric = getLastMetric(series); if (!/_bucket$/.test(metric.type)) return next(results); if (metric.type === 'std_deviation_bucket' && metric.mode === 'band') return next(results); const fakeResp = { aggregations: bucket }; - getSplits(fakeResp, panel, series).forEach((split) => { + (await getSplits(fakeResp, panel, series, meta, extractFields)).forEach((split) => { const data = split.timeseries.buckets.map((b) => { return [b.key, getSiblingAggValue(split, metric)]; }); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/series/build_request_body.test.ts b/src/plugins/vis_type_timeseries/server/lib/vis_data/series/build_request_body.test.ts index 6b2ef320d54b7..64cd3bf7a7dea 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/series/build_request_body.test.ts +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/series/build_request_body.test.ts @@ -78,7 +78,7 @@ const body = JSON.parse(` `); describe('buildRequestBody(req)', () => { - test('returns a valid body', () => { + test('returns a valid body', async () => { const panel = body.panels[0]; const series = panel.series[0]; const getValidTimeInterval = jest.fn(() => '10s'); @@ -91,14 +91,16 @@ describe('buildRequestBody(req)', () => { queryStringOptions: {}, }; const indexPatternObject = {}; - const doc = buildRequestBody( + const doc = await buildRequestBody( { payload: body }, panel, series, config, indexPatternObject, capabilities, - { barTargetUiSettings: 50 } + { + get: async () => 50, + } ); expect(doc).toEqual({ diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/series/build_request_body.ts b/src/plugins/vis_type_timeseries/server/lib/vis_data/series/build_request_body.ts index 9d8f3fca789f0..45d3d788df4f3 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/series/build_request_body.ts +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/series/build_request_body.ts @@ -34,8 +34,8 @@ import { processors } from '../request_processors/series/index'; * ] * @returns {Object} doc - processed body */ -export function buildRequestBody(...args: any[]) { +export async function buildRequestBody(...args: any[]) { const processor = buildProcessorFunction(processors, ...args); - const doc = processor({}); + const doc = await processor({}); return doc; } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/series/get_request_params.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/series/get_request_params.js index 3804b1407b086..ca4f631f9ea70 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/series/get_request_params.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/series/get_request_params.js @@ -19,7 +19,6 @@ import { buildRequestBody } from './build_request_body'; import { getEsShardTimeout } from '../helpers/get_es_shard_timeout'; import { getIndexPatternObject } from '../helpers/get_index_pattern'; -import { UI_SETTINGS } from '../../../../../data/common'; export async function getSeriesRequestParams(req, panel, series, esQueryConfig, capabilities) { const uiSettings = req.getUiSettingsService(); @@ -27,17 +26,14 @@ export async function getSeriesRequestParams(req, panel, series, esQueryConfig, (series.override_index_pattern && series.series_index_pattern) || panel.index_pattern; const { indexPatternObject, indexPatternString } = await getIndexPatternObject(req, indexPattern); - const request = buildRequestBody( + const request = await buildRequestBody( req, panel, series, esQueryConfig, indexPatternObject, capabilities, - { - maxBarsUiSettings: await uiSettings.get(UI_SETTINGS.HISTOGRAM_MAX_BARS), - barTargetUiSettings: await uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET), - } + uiSettings ); const esShardTimeout = await getEsShardTimeout(req); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/series/handle_response_body.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/series/handle_response_body.js index eef7143990e98..c04e56de57a4e 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/series/handle_response_body.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/series/handle_response_body.js @@ -21,9 +21,10 @@ import { buildProcessorFunction } from '../build_processor_function'; import { processors } from '../response_processors/series'; import { get } from 'lodash'; import { i18n } from '@kbn/i18n'; +import { createFieldsFetcher } from './../helpers/fields_fetcher'; -export function handleResponseBody(panel) { - return (resp) => { +export function handleResponseBody(panel, req, searchStrategy, capabilities) { + return async (resp) => { if (resp.error) { const err = new Error(resp.error.type); err.response = JSON.stringify(resp); @@ -48,8 +49,11 @@ export function handleResponseBody(panel) { const [seriesId] = keys; const meta = get(resp, `aggregations.${seriesId}.meta`, {}); const series = panel.series.find((s) => s.id === (meta.seriesId || seriesId)); - const processor = buildProcessorFunction(processors, resp, panel, series, meta); - return processor([]); + const extractFields = createFieldsFetcher(req, searchStrategy, capabilities); + + const processor = buildProcessorFunction(processors, resp, panel, series, meta, extractFields); + + return await processor([]); }; } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/table/build_request_body.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/table/build_request_body.js index 7715c803d374b..3fcf38bb07e20 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/table/build_request_body.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/table/build_request_body.js @@ -20,8 +20,8 @@ import { buildProcessorFunction } from '../build_processor_function'; import { processors } from '../request_processors/table'; -export function buildRequestBody(...args) { +export async function buildRequestBody(...args) { const processor = buildProcessorFunction(processors, ...args); - const doc = processor({}); + const doc = await processor({}); return doc; } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/table/process_bucket.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/table/process_bucket.js index 909cee456c31f..9604904af2c7d 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/table/process_bucket.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/table/process_bucket.js @@ -34,27 +34,40 @@ function trendSinceLastBucket(data) { return Number.isNaN(trend) ? 0 : trend; } -export function processBucket(panel) { - return (bucket) => { - const series = getActiveSeries(panel).map((series) => { - const timeseries = get(bucket, `${series.id}.timeseries`); - const buckets = get(bucket, `${series.id}.buckets`); +export function processBucket(panel, req, searchStrategy, capabilities, extractFields) { + return async (bucket) => { + const series = await Promise.all( + getActiveSeries(panel).map(async (series) => { + const timeseries = get(bucket, `${series.id}.timeseries`); + const buckets = get(bucket, `${series.id}.buckets`); + let meta = {}; + + if (!timeseries && buckets) { + meta = get(bucket, `${series.id}.meta`); + const timeseries = { + buckets: get(bucket, `${series.id}.buckets`), + }; + overwrite(bucket, series.id, { meta, timeseries }); + } + + const processor = buildProcessorFunction( + processors, + bucket, + panel, + series, + meta, + extractFields + ); + const result = first(await processor([])); + + if (!result) return null; + const data = get(result, 'data', []); + result.slope = trendSinceLastBucket(data); + result.last = getLastValue(data); + return result; + }) + ); - if (!timeseries && buckets) { - const meta = get(bucket, `${series.id}.meta`); - const timeseries = { - buckets: get(bucket, `${series.id}.buckets`), - }; - overwrite(bucket, series.id, { meta, timeseries }); - } - const processor = buildProcessorFunction(processors, bucket, panel, series); - const result = first(processor([])); - if (!result) return null; - const data = get(result, 'data', []); - result.slope = trendSinceLastBucket(data); - result.last = getLastValue(data); - return result; - }); return { key: bucket.key, series }; }; } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/table/process_bucket.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/table/process_bucket.test.js index a4f9c71a5953d..83479468e7199 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/table/process_bucket.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/table/process_bucket.test.js @@ -94,17 +94,17 @@ describe('processBucket(panel)', () => { panel = createPanel([SERIES_ID]); }); - test('return the correct trend direction', () => { + test('return the correct trend direction', async () => { const bucketProcessor = processBucket(panel); const buckets = createBuckets([SERIES_ID]); for (const bucket of buckets) { - const result = bucketProcessor(bucket); + const result = await bucketProcessor(bucket); expect(result.key).toEqual(bucket.key); expect(trendChecker(bucket.expectedTrend, result.series[0].slope)).toBeTruthy(); } }); - test('properly handle 0 values for trend', () => { + test('properly handle 0 values for trend', async () => { const bucketProcessor = processBucket(panel); const bucketforNaNResult = { key: 'NaNScenario', @@ -121,16 +121,18 @@ describe('processBucket(panel)', () => { ], }, }; - const result = bucketProcessor(bucketforNaNResult); + const result = await bucketProcessor(bucketforNaNResult); expect(result.key).toEqual(bucketforNaNResult.key); expect(trendChecker(bucketforNaNResult.expectedTrend, result.series[0].slope)).toEqual(true); }); - test('have the side effect to create the timeseries property if missing on bucket', () => { + test('have the side effect to create the timeseries property if missing on bucket', async () => { const bucketProcessor = processBucket(panel); const buckets = createBuckets([SERIES_ID]); + for (const bucket of buckets) { - bucketProcessor(bucket); + await bucketProcessor(bucket); + expect(bucket[SERIES_ID].buckets).toBeUndefined(); expect(bucket[SERIES_ID].timeseries).toBeDefined(); } @@ -145,11 +147,12 @@ describe('processBucket(panel)', () => { panel = createPanel(SERIES); }); - test('return the correct trend direction', () => { + test('return the correct trend direction', async () => { const bucketProcessor = processBucket(panel); const buckets = createBuckets(SERIES); for (const bucket of buckets) { - const result = bucketProcessor(bucket); + const result = await bucketProcessor(bucket); + expect(result.key).toEqual(bucket.key); expect(trendChecker(bucket.expectedTrend, result.series[0].slope)).toBeTruthy(); expect(trendChecker(bucket.expectedTrend, result.series[1].slope)).toBeTruthy(); diff --git a/test/functional/page_objects/visual_builder_page.ts b/test/functional/page_objects/visual_builder_page.ts index 5b07cb0e534db..7541d9e5cf3d7 100644 --- a/test/functional/page_objects/visual_builder_page.ts +++ b/test/functional/page_objects/visual_builder_page.ts @@ -61,6 +61,9 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrPro let isPresent = false; await retry.try(async () => { isPresent = await testSubjects.exists(testSubj, { timeout: 20000 }); + if (!isPresent) { + isPresent = await testSubjects.exists('visNoResult', { timeout: 1000 }); + } }); if (!isPresent) { throw new Error(`TSVB ${name} tab is not loaded`); diff --git a/x-pack/plugins/vis_type_timeseries_enhanced/server/search_strategies/rollup_search_strategy.test.ts b/x-pack/plugins/vis_type_timeseries_enhanced/server/search_strategies/rollup_search_strategy.test.ts index ec6c91b616f5b..e3fbe2daa3756 100644 --- a/x-pack/plugins/vis_type_timeseries_enhanced/server/search_strategies/rollup_search_strategy.test.ts +++ b/x-pack/plugins/vis_type_timeseries_enhanced/server/search_strategies/rollup_search_strategy.test.ts @@ -12,11 +12,11 @@ jest.mock('../../../../../src/plugins/vis_type_timeseries/server', () => { getFieldsForWildcard() { return [ { - name: 'day_of_week.terms.value', + name: 'day_of_week', type: 'object', esTypes: ['object'], - searchable: false, - aggregatable: false, + searchable: true, + aggregatable: true, }, ]; } @@ -157,7 +157,6 @@ describe('Rollup Search Strategy', () => { { aggregatable: true, name: 'day_of_week', - readFromDocValues: true, searchable: true, type: 'object', esTypes: ['object'], diff --git a/x-pack/plugins/vis_type_timeseries_enhanced/server/search_strategies/rollup_search_strategy.ts b/x-pack/plugins/vis_type_timeseries_enhanced/server/search_strategies/rollup_search_strategy.ts index f1c20c318d109..60fa51d0995db 100644 --- a/x-pack/plugins/vis_type_timeseries_enhanced/server/search_strategies/rollup_search_strategy.ts +++ b/x-pack/plugins/vis_type_timeseries_enhanced/server/search_strategies/rollup_search_strategy.ts @@ -3,24 +3,20 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { keyBy, isString } from 'lodash'; import { AbstractSearchStrategy, ReqFacade, VisPayload, } from '../../../../../src/plugins/vis_type_timeseries/server'; -import { - mergeCapabilitiesWithFields, - getCapabilitiesForRollupIndices, -} from '../../../../../src/plugins/data/server'; +import { getCapabilitiesForRollupIndices } from '../../../../../src/plugins/data/server'; import { RollupSearchCapabilities } from './rollup_search_capabilities'; const getRollupIndices = (rollupData: { [key: string]: any }) => Object.keys(rollupData); const isIndexPatternContainsWildcard = (indexPattern: string) => indexPattern.includes('*'); const isIndexPatternValid = (indexPattern: string) => - indexPattern && isString(indexPattern) && !isIndexPatternContainsWildcard(indexPattern); + indexPattern && typeof indexPattern === 'string' && !isIndexPatternContainsWildcard(indexPattern); export class RollupSearchStrategy extends AbstractSearchStrategy { name = 'rollup'; @@ -65,15 +61,11 @@ export class RollupSearchStrategy extends AbstractSearchStrategy { async getFieldsForWildcard( req: ReqFacade, indexPattern: string, - { - fieldsCapabilities, - rollupIndex, - }: { fieldsCapabilities: { [key: string]: any }; rollupIndex: string } + capabilities?: unknown ) { - const fields = await super.getFieldsForWildcard(req, indexPattern); - const fieldsFromFieldCapsApi = keyBy(fields, 'name'); - const rollupIndexCapabilities = fieldsCapabilities[rollupIndex].aggs; - - return mergeCapabilitiesWithFields(rollupIndexCapabilities, fieldsFromFieldCapsApi); + return super.getFieldsForWildcard(req, indexPattern, capabilities, { + type: 'rollup', + rollupIndex: indexPattern, + }); } } From 807e8bdeb22c33ae170f3d41c9e7afa446e275f1 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Tue, 12 Jan 2021 17:33:07 +0100 Subject: [PATCH 42/64] Kibana app and presentation ts projects (#87639) --- src/plugins/advanced_settings/tsconfig.json | 21 ++++++++++++ src/plugins/charts/tsconfig.json | 16 +++++++++ .../dashboard/.storybook/storyshots.test.tsx | 2 ++ src/plugins/dashboard/kibana.json | 17 +++++++--- src/plugins/dashboard/tsconfig.json | 34 +++++++++++++++++++ src/plugins/discover/tsconfig.json | 28 +++++++++++++++ src/plugins/input_control_vis/kibana.json | 11 ++++-- src/plugins/presentation_util/tsconfig.json | 16 +++++++++ src/plugins/vis_type_markdown/kibana.json | 12 +++++-- test/tsconfig.json | 5 +++ tsconfig.json | 15 ++++++-- tsconfig.refs.json | 7 ++++ x-pack/plugins/canvas/kibana.json | 29 ++++++++++++++-- x-pack/plugins/dashboard_enhanced/kibana.json | 17 +++++++--- .../plugins/dashboard_enhanced/tsconfig.json | 25 ++++++++++++++ x-pack/plugins/graph/tsconfig.json | 30 ++++++++++++++++ x-pack/test/tsconfig.json | 4 +++ x-pack/tsconfig.json | 10 +++++- x-pack/tsconfig.refs.json | 2 ++ 19 files changed, 281 insertions(+), 20 deletions(-) create mode 100644 src/plugins/advanced_settings/tsconfig.json create mode 100644 src/plugins/charts/tsconfig.json create mode 100644 src/plugins/dashboard/tsconfig.json create mode 100644 src/plugins/discover/tsconfig.json create mode 100644 src/plugins/presentation_util/tsconfig.json create mode 100644 x-pack/plugins/dashboard_enhanced/tsconfig.json create mode 100644 x-pack/plugins/graph/tsconfig.json diff --git a/src/plugins/advanced_settings/tsconfig.json b/src/plugins/advanced_settings/tsconfig.json new file mode 100644 index 0000000000000..4d62e410326b6 --- /dev/null +++ b/src/plugins/advanced_settings/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": [ + "public/**/*", + "server/**/*" + ], + "references": [ + { "path": "../../core/tsconfig.json" }, + { "path": "../management/tsconfig.json" }, + { "path": "../home/tsconfig.json" }, + { "path": "../usage_collection/tsconfig.json" }, + { "path": "../kibana_react/tsconfig.json" }, + ] +} diff --git a/src/plugins/charts/tsconfig.json b/src/plugins/charts/tsconfig.json new file mode 100644 index 0000000000000..a4f65d5937204 --- /dev/null +++ b/src/plugins/charts/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": ["common/**/*", "public/**/*", "server/**/*"], + "references": [ + { "path": "../../core/tsconfig.json" }, + { "path": "../expressions/tsconfig.json" }, + { "path": "../embeddable/tsconfig.json" } + ] +} diff --git a/src/plugins/dashboard/.storybook/storyshots.test.tsx b/src/plugins/dashboard/.storybook/storyshots.test.tsx index af8e71c77231a..3b4d5df350bf2 100644 --- a/src/plugins/dashboard/.storybook/storyshots.test.tsx +++ b/src/plugins/dashboard/.storybook/storyshots.test.tsx @@ -12,6 +12,7 @@ import 'moment-timezone'; import ReactDOM from 'react-dom'; import initStoryshots, { multiSnapshotWithOptions } from '@storybook/addon-storyshots'; +// @ts-ignore import styleSheetSerializer from 'jest-styled-components/src/styleSheetSerializer'; import { addSerializer } from 'jest-specific-snapshot'; @@ -52,6 +53,7 @@ jest.mock('@elastic/eui/lib/components/overlay_mask/overlay_mask', () => { }; }); +// @ts-ignore import { EuiObserver } from '@elastic/eui/test-env/components/observer/observer'; jest.mock('@elastic/eui/test-env/components/observer/observer'); EuiObserver.mockImplementation(() => 'EuiObserver'); diff --git a/src/plugins/dashboard/kibana.json b/src/plugins/dashboard/kibana.json index b5451203e2365..e074d529917d2 100644 --- a/src/plugins/dashboard/kibana.json +++ b/src/plugins/dashboard/kibana.json @@ -6,14 +6,21 @@ "embeddable", "inspector", "kibanaLegacy", - "urlForwarding", "navigation", - "uiActions", "savedObjects", - "share" + "share", + "uiActions", + "urlForwarding" ], - "optionalPlugins": ["home", "usageCollection", "savedObjectsTaggingOss"], + "optionalPlugins": [ + "home", + "savedObjectsTaggingOss", + "usageCollection"], "server": true, "ui": true, - "requiredBundles": ["kibanaUtils", "kibanaReact", "home"] + "requiredBundles": [ + "home", + "kibanaReact", + "kibanaUtils" + ] } diff --git a/src/plugins/dashboard/tsconfig.json b/src/plugins/dashboard/tsconfig.json new file mode 100644 index 0000000000000..c70f2bad7e701 --- /dev/null +++ b/src/plugins/dashboard/tsconfig.json @@ -0,0 +1,34 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": [ + "*.ts", + ".storybook/**/*", + "common/**/*", + "public/**/*", + "server/**/*", + ], + "references": [ + { "path": "../../core/tsconfig.json" }, + { "path": "../inspector/tsconfig.json" }, + { "path": "../kibana_legacy/tsconfig.json" }, + { "path": "../kibana_react/tsconfig.json" }, + { "path": "../kibana_utils/tsconfig.json" }, + { "path": "../share/tsconfig.json" }, + { "path": "../url_forwarding/tsconfig.json" }, + { "path": "../usage_collection/tsconfig.json" }, + { "path": "../data/tsconfig.json"}, + { "path": "../embeddable/tsconfig.json" }, + { "path": "../home/tsconfig.json" }, + { "path": "../navigation/tsconfig.json" }, + { "path": "../saved_objects_tagging_oss/tsconfig.json" }, + { "path": "../saved_objects/tsconfig.json" }, + { "path": "../ui_actions/tsconfig.json" }, + ] +} diff --git a/src/plugins/discover/tsconfig.json b/src/plugins/discover/tsconfig.json new file mode 100644 index 0000000000000..ec98199c3423e --- /dev/null +++ b/src/plugins/discover/tsconfig.json @@ -0,0 +1,28 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": ["common/**/*", "public/**/*", "server/**/*", "../../../typings/**/*"], + "references": [ + { "path": "../../core/tsconfig.json" }, + { "path": "../charts/tsconfig.json" }, + { "path": "../data/tsconfig.json" }, + { "path": "../embeddable/tsconfig.json" }, + { "path": "../inspector/tsconfig.json" }, + { "path": "../url_forwarding/tsconfig.json" }, + { "path": "../saved_objects/tsconfig.json" }, + { "path": "../navigation/tsconfig.json" }, + { "path": "../ui_actions/tsconfig.json" }, + { "path": "../home/tsconfig.json" }, + { "path": "../share/tsconfig.json" }, + { "path": "../usage_collection/tsconfig.json" }, + { "path": "../kibana_utils/tsconfig.json" }, + { "path": "../kibana_react/tsconfig.json" }, + { "path": "../kibana_legacy/tsconfig.json" } + ] +} diff --git a/src/plugins/input_control_vis/kibana.json b/src/plugins/input_control_vis/kibana.json index c6d1157f5ff25..5acb79a8ab038 100644 --- a/src/plugins/input_control_vis/kibana.json +++ b/src/plugins/input_control_vis/kibana.json @@ -4,6 +4,13 @@ "kibanaVersion": "kibana", "server": true, "ui": true, - "requiredPlugins": ["data", "expressions", "visualizations", "visDefaultEditor"], - "requiredBundles": ["kibanaReact"] + "requiredPlugins": [ + "data", + "expressions", + "visDefaultEditor", + "visualizations" + ], + "requiredBundles": [ + "kibanaReact" + ] } diff --git a/src/plugins/presentation_util/tsconfig.json b/src/plugins/presentation_util/tsconfig.json new file mode 100644 index 0000000000000..1e3756f45e953 --- /dev/null +++ b/src/plugins/presentation_util/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": ["common/**/*", "public/**/*"], + "references": [ + { "path": "../../core/tsconfig.json" }, + { "path": "../dashboard/tsconfig.json" }, + { "path": "../saved_objects/tsconfig.json" }, + ] +} diff --git a/src/plugins/vis_type_markdown/kibana.json b/src/plugins/vis_type_markdown/kibana.json index 6cfedf60687ef..e14b4fe7bce96 100644 --- a/src/plugins/vis_type_markdown/kibana.json +++ b/src/plugins/vis_type_markdown/kibana.json @@ -3,6 +3,14 @@ "version": "kibana", "ui": true, "server": true, - "requiredPlugins": ["expressions", "visualizations"], - "requiredBundles": ["kibanaReact", "visualizations", "expressions", "visDefaultEditor"] + "requiredPlugins": [ + "expressions", + "visualizations" + ], + "requiredBundles": [ + "expressions", + "kibanaReact", + "visDefaultEditor", + "visualizations" + ] } diff --git a/test/tsconfig.json b/test/tsconfig.json index f9008505ed66e..f1d5115bf35fb 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -8,8 +8,12 @@ "exclude": ["plugin_functional/plugins/**/*", "interpreter_functional/plugins/**/*"], "references": [ { "path": "../src/core/tsconfig.json" }, + { "path": "../src/plugins/advanced_settings/tsconfig.json" }, { "path": "../src/plugins/management/tsconfig.json" }, { "path": "../src/plugins/bfetch/tsconfig.json" }, + { "path": "../src/plugins/charts/tsconfig.json" }, + { "path": "../src/plugins/dashboard/tsconfig.json" }, + { "path": "../src/plugins/discover/tsconfig.json" }, { "path": "../src/plugins/embeddable/tsconfig.json" }, { "path": "../src/plugins/expressions/tsconfig.json" }, { "path": "../src/plugins/home/tsconfig.json" }, @@ -24,6 +28,7 @@ { "path": "../src/plugins/telemetry_collection_manager/tsconfig.json" }, { "path": "../src/plugins/telemetry/tsconfig.json" }, { "path": "../src/plugins/ui_actions/tsconfig.json" }, + { "path": "../src/plugins/url_forwarding/tsconfig.json" }, { "path": "../src/plugins/usage_collection/tsconfig.json" }, ] } diff --git a/tsconfig.json b/tsconfig.json index 20e2e57ce654e..259449c67444a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,9 +7,12 @@ "exclude": [ "src/**/__fixtures__/**/*", "src/core/**/*", - "src/plugins/management/**/*", + "src/plugins/advanced_settings/**/*", "src/plugins/apm_oss/**/*", "src/plugins/bfetch/**/*", + "src/plugins/charts/**/*", + "src/plugins/dashboard/**/*", + "src/plugins/discover/**/*", "src/plugins/data/**/*", "src/plugins/dev_tools/**/*", "src/plugins/embeddable/**/*", @@ -20,6 +23,7 @@ "src/plugins/kibana_react/**/*", "src/plugins/kibana_usage_collection/**/*", "src/plugins/kibana_utils/**/*", + "src/plugins/management/**/*", "src/plugins/navigation/**/*", "src/plugins/newsfeed/**/*", "src/plugins/saved_objects/**/*", @@ -30,7 +34,8 @@ "src/plugins/telemetry_collection_manager/**/*", "src/plugins/ui_actions/**/*", "src/plugins/url_forwarding/**/*", - "src/plugins/usage_collection/**/*" + "src/plugins/usage_collection/**/*", + "src/plugins/presentation_util/**/*" // In the build we actually exclude **/public/**/* from this config so that // we can run the TSC on both this and the .browser version of this config // file, but if we did it during development IDEs would not be able to find @@ -39,9 +44,12 @@ ], "references": [ { "path": "./src/core/tsconfig.json" }, - { "path": "./src/plugins/management/tsconfig.json"}, + { "path": "./src/plugins/advanced_settings/tsconfig.json" }, { "path": "./src/plugins/apm_oss/tsconfig.json" }, { "path": "./src/plugins/bfetch/tsconfig.json" }, + { "path": "./src/plugins/charts/tsconfig.json" }, + { "path": "./src/plugins/dashboard/tsconfig.json" }, + { "path": "./src/plugins/discover/tsconfig.json" }, { "path": "./src/plugins/data/tsconfig.json" }, { "path": "./src/plugins/dev_tools/tsconfig.json" }, { "path": "./src/plugins/embeddable/tsconfig.json" }, @@ -52,6 +60,7 @@ { "path": "./src/plugins/kibana_react/tsconfig.json" }, { "path": "./src/plugins/kibana_usage_collection/tsconfig.json" }, { "path": "./src/plugins/kibana_utils/tsconfig.json" }, + { "path": "./src/plugins/management/tsconfig.json" }, { "path": "./src/plugins/navigation/tsconfig.json" }, { "path": "./src/plugins/newsfeed/tsconfig.json" }, { "path": "./src/plugins/saved_objects/tsconfig.json" }, diff --git a/tsconfig.refs.json b/tsconfig.refs.json index c27d2ff2ec6f0..91ee34c490f7b 100644 --- a/tsconfig.refs.json +++ b/tsconfig.refs.json @@ -2,22 +2,29 @@ "include": [], "references": [ { "path": "./src/core/tsconfig.json" }, + { "path": "./src/plugins/advanced_settings/tsconfig.json" }, { "path": "./src/plugins/apm_oss/tsconfig.json" }, { "path": "./src/plugins/bfetch/tsconfig.json" }, + { "path": "./src/plugins/charts/tsconfig.json" }, { "path": "./src/plugins/data/tsconfig.json" }, { "path": "./src/plugins/dev_tools/tsconfig.json" }, + { "path": "./src/plugins/discover/tsconfig.json" }, { "path": "./src/plugins/embeddable/tsconfig.json" }, { "path": "./src/plugins/expressions/tsconfig.json" }, { "path": "./src/plugins/home/tsconfig.json" }, + { "path": "./src/plugins/dashboard/tsconfig.json" }, + { "path": "./src/plugins/dev_tools/tsconfig.json" }, { "path": "./src/plugins/inspector/tsconfig.json" }, { "path": "./src/plugins/kibana_legacy/tsconfig.json" }, { "path": "./src/plugins/kibana_react/tsconfig.json" }, { "path": "./src/plugins/kibana_usage_collection/tsconfig.json" }, { "path": "./src/plugins/kibana_utils/tsconfig.json" }, + { "path": "./src/plugins/management/tsconfig.json" }, { "path": "./src/plugins/navigation/tsconfig.json" }, { "path": "./src/plugins/newsfeed/tsconfig.json" }, { "path": "./src/plugins/saved_objects/tsconfig.json" }, { "path": "./src/plugins/saved_objects_tagging_oss/tsconfig.json" }, + { "path": "./src/plugins/presentation_util/tsconfig.json" }, { "path": "./src/plugins/security_oss/tsconfig.json" }, { "path": "./src/plugins/share/tsconfig.json" }, { "path": "./src/plugins/telemetry/tsconfig.json" }, diff --git a/x-pack/plugins/canvas/kibana.json b/x-pack/plugins/canvas/kibana.json index 38bbb074f6dbd..c14e8340957ad 100644 --- a/x-pack/plugins/canvas/kibana.json +++ b/x-pack/plugins/canvas/kibana.json @@ -5,7 +5,30 @@ "configPath": ["xpack", "canvas"], "server": true, "ui": true, - "requiredPlugins": ["bfetch", "data", "embeddable", "expressions", "features", "inspector", "uiActions", "charts"], - "optionalPlugins": ["usageCollection", "home"], - "requiredBundles": ["kibanaReact", "maps", "lens", "visualizations", "kibanaUtils", "kibanaLegacy", "discover", "savedObjects", "reporting", "home"] + "requiredPlugins": [ + "bfetch", + "charts", + "data", + "embeddable", + "expressions", + "features", + "inspector", + "uiActions" + ], + "optionalPlugins": [ + "home", + "usageCollection" + ], + "requiredBundles": [ + "discover", + "home", + "kibanaLegacy", + "kibanaReact", + "kibanaUtils", + "lens", + "maps", + "reporting", + "savedObjects", + "visualizations" + ] } diff --git a/x-pack/plugins/dashboard_enhanced/kibana.json b/x-pack/plugins/dashboard_enhanced/kibana.json index d3a1f29f0c7ff..0f2e790ff91ad 100644 --- a/x-pack/plugins/dashboard_enhanced/kibana.json +++ b/x-pack/plugins/dashboard_enhanced/kibana.json @@ -3,12 +3,21 @@ "version": "kibana", "server": true, "ui": true, - "requiredPlugins": ["data", "uiActionsEnhanced", "embeddable", "dashboard", "share"], - "configPath": ["xpack", "dashboardEnhanced"], + "configPath": [ + "xpack", + "dashboardEnhanced" + ], + "requiredPlugins": [ + "dashboard", + "data", + "embeddable", + "share", + "uiActionsEnhanced" + ], "requiredBundles": [ "embeddable", - "kibanaUtils", "embeddableEnhanced", - "kibanaReact" + "kibanaReact", + "kibanaUtils" ] } diff --git a/x-pack/plugins/dashboard_enhanced/tsconfig.json b/x-pack/plugins/dashboard_enhanced/tsconfig.json new file mode 100644 index 0000000000000..567c390edfa5a --- /dev/null +++ b/x-pack/plugins/dashboard_enhanced/tsconfig.json @@ -0,0 +1,25 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": [ + "common/**/*", + "public/**/*", + "server/**/*", + ], + "references": [ + { "path": "../../../src/plugins/kibana_react/tsconfig.json" }, + { "path": "../../../src/plugins/kibana_utils/tsconfig.json" }, + { "path": "../../../src/plugins/dashboard/tsconfig.json" }, + { "path": "../../../src/plugins/share/tsconfig.json" }, + { "path": "../../../src/plugins/data/tsconfig.json"}, + { "path": "../../../src/plugins/embeddable/tsconfig.json" }, + { "path": "../embeddable_enhanced/tsconfig.json" }, + { "path": "../ui_actions_enhanced/tsconfig.json" }, + ] +} diff --git a/x-pack/plugins/graph/tsconfig.json b/x-pack/plugins/graph/tsconfig.json new file mode 100644 index 0000000000000..741c603e3aae4 --- /dev/null +++ b/x-pack/plugins/graph/tsconfig.json @@ -0,0 +1,30 @@ + +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": [ + "*.ts", + "common/**/*", + "public/**/*", + "server/**/*", + "../../../typings/**/*", + ], + "references": [ + { "path": "../../../src/core/tsconfig.json" }, + { "path": "../licensing/tsconfig.json" }, + { "path": "../features/tsconfig.json"}, + { "path": "../../../src/plugins/data/tsconfig.json"}, + { "path": "../../../src/plugins/navigation/tsconfig.json" }, + { "path": "../../../src/plugins/saved_objects/tsconfig.json"}, + { "path": "../../../src/plugins/kibana_legacy/tsconfig.json"}, + { "path": "../../../src/plugins/home/tsconfig.json"}, + { "path": "../../../src/plugins/kibana_utils/tsconfig.json" }, + { "path": "../../../src/plugins/kibana_react/tsconfig.json" } + ] + } \ No newline at end of file diff --git a/x-pack/test/tsconfig.json b/x-pack/test/tsconfig.json index 27c43abf1401e..2584cedd01523 100644 --- a/x-pack/test/tsconfig.json +++ b/x-pack/test/tsconfig.json @@ -11,6 +11,9 @@ { "path": "../../src/core/tsconfig.json" }, { "path": "../../src/plugins/management/tsconfig.json" }, { "path": "../../src/plugins/bfetch/tsconfig.json" }, + { "path": "../../src/plugins/charts/tsconfig.json" }, + { "path": "../../src/plugins/dashboard/tsconfig.json" }, + { "path": "../../src/plugins/discover/tsconfig.json" }, { "path": "../../src/plugins/data/tsconfig.json" }, { "path": "../../src/plugins/embeddable/tsconfig.json" }, { "path": "../../src/plugins/expressions/tsconfig.json" }, @@ -27,6 +30,7 @@ { "path": "../../src/plugins/telemetry/tsconfig.json" }, { "path": "../../src/plugins/usage_collection/tsconfig.json" }, { "path": "../../src/plugins/ui_actions/tsconfig.json" }, + { "path": "../../src/plugins/url_forwarding/tsconfig.json" }, { "path": "../plugins/data_enhanced/tsconfig.json" }, { "path": "../plugins/global_search/tsconfig.json" }, diff --git a/x-pack/tsconfig.json b/x-pack/tsconfig.json index a5911c9870f6d..12725d17c0b63 100644 --- a/x-pack/tsconfig.json +++ b/x-pack/tsconfig.json @@ -5,7 +5,9 @@ "plugins/apm/e2e/cypress/**/*", "plugins/apm/scripts/**/*", "plugins/data_enhanced/**/*", + "plugins/dashboard_enhanced/**/*", "plugins/global_search/**/*", + "plugins/graph/**/*", "plugins/features/**/*", "plugins/embeddable_enhanced/**/*", "plugins/licensing/**/*", @@ -23,6 +25,9 @@ { "path": "../src/core/tsconfig.json" }, { "path": "../src/plugins/management/tsconfig.json" }, { "path": "../src/plugins/bfetch/tsconfig.json" }, + { "path": "../src/plugins/charts/tsconfig.json" }, + { "path": "../src/plugins/dashboard/tsconfig.json" }, + { "path": "../src/plugins/discover/tsconfig.json" }, { "path": "../src/plugins/data/tsconfig.json" }, { "path": "../src/plugins/dev_tools/tsconfig.json" }, { "path": "../src/plugins/embeddable/tsconfig.json" }, @@ -37,21 +42,24 @@ { "path": "../src/plugins/newsfeed/tsconfig.json" }, { "path": "../src/plugins/saved_objects/tsconfig.json" }, { "path": "../src/plugins/saved_objects_tagging_oss/tsconfig.json" }, + { "path": "../src/plugins/presentation_util/tsconfig.json" }, { "path": "../src/plugins/security_oss/tsconfig.json" }, { "path": "../src/plugins/share/tsconfig.json" }, { "path": "../src/plugins/telemetry/tsconfig.json" }, { "path": "../src/plugins/telemetry_collection_manager/tsconfig.json" }, { "path": "../src/plugins/url_forwarding/tsconfig.json" }, { "path": "../src/plugins/ui_actions/tsconfig.json" }, + { "path": "../src/plugins/url_forwarding/tsconfig.json" }, { "path": "../src/plugins/usage_collection/tsconfig.json" }, { "path": "./plugins/data_enhanced/tsconfig.json" }, { "path": "./plugins/global_search/tsconfig.json" }, { "path": "./plugins/features/tsconfig.json" }, + { "path": "./plugins/graph/tsconfig.json" }, { "path": "./plugins/embeddable_enhanced/tsconfig.json" }, { "path": "./plugins/licensing/tsconfig.json" }, { "path": "./plugins/task_manager/tsconfig.json" }, { "path": "./plugins/telemetry_collection_xpack/tsconfig.json" }, - { "path": "./plugins/ui_actions_enhanced/tsconfig.json" } + { "path": "./plugins/ui_actions_enhanced/tsconfig.json" }, ] } diff --git a/x-pack/tsconfig.refs.json b/x-pack/tsconfig.refs.json index d5012df00beb0..6f54ac9087e2b 100644 --- a/x-pack/tsconfig.refs.json +++ b/x-pack/tsconfig.refs.json @@ -1,10 +1,12 @@ { "include": [], "references": [ + { "path": "./plugins/dashboard_enhanced/tsconfig.json" }, { "path": "./plugins/licensing/tsconfig.json" }, { "path": "./plugins/data_enhanced/tsconfig.json" }, { "path": "./plugins/global_search/tsconfig.json" }, { "path": "./plugins/features/tsconfig.json" }, + { "path": "./plugins/graph/tsconfig.json" }, { "path": "./plugins/embeddable_enhanced/tsconfig.json" }, { "path": "./plugins/task_manager/tsconfig.json" }, { "path": "./plugins/telemetry_collection_xpack/tsconfig.json" }, From 1a9836b29675ba29a55a408a156ea0b921836f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20G=C3=B3mez?= Date: Tue, 12 Jan 2021 17:33:50 +0100 Subject: [PATCH 43/64] [Logs UI] Add documentation to the infra Storybook (#87169) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Felix Stürmer --- package.json | 3 +- .../public/components/log_stream/README.md | 171 --------- .../log_stream/log_stream.stories.mdx | 348 ++++++++++++++++++ .../infra/public/test_utils/entries.ts | 73 ++++ .../public/test_utils/source_configuration.ts | 46 +++ yarn.lock | 13 +- 6 files changed, 478 insertions(+), 176 deletions(-) delete mode 100644 x-pack/plugins/infra/public/components/log_stream/README.md create mode 100644 x-pack/plugins/infra/public/components/log_stream/log_stream.stories.mdx create mode 100644 x-pack/plugins/infra/public/test_utils/entries.ts create mode 100644 x-pack/plugins/infra/public/test_utils/source_configuration.ts diff --git a/package.json b/package.json index 8a3a8151f8910..edeeebdddabf1 100644 --- a/package.json +++ b/package.json @@ -440,6 +440,7 @@ "@types/enzyme": "^3.10.5", "@types/eslint": "^6.1.3", "@types/extract-zip": "^1.6.2", + "@types/faker": "^5.1.5", "@types/fancy-log": "^1.3.1", "@types/fetch-mock": "^7.3.1", "@types/file-saver": "^2.0.0", @@ -647,7 +648,7 @@ "eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-react-perf": "^3.2.3", "expose-loader": "^0.7.5", - "faker": "1.1.0", + "faker": "^5.1.0", "fancy-log": "^1.3.2", "fast-glob": "2.2.7", "fetch-mock": "^7.3.9", diff --git a/x-pack/plugins/infra/public/components/log_stream/README.md b/x-pack/plugins/infra/public/components/log_stream/README.md deleted file mode 100644 index 6ddbddb6bcdd8..0000000000000 --- a/x-pack/plugins/infra/public/components/log_stream/README.md +++ /dev/null @@ -1,171 +0,0 @@ -# Embeddable `` component - -The purpose of this component is to allow you, the developer, to have your very own Log Stream in your plugin. - -The plugin is exposed through `infra/public`. Since Kibana uses relative paths is up to you to find how to import it (sorry). - -```tsx -import { LogStream } from '../../../../../../infra/public'; -``` - -## Prerequisites - -To use the component, there are several things you need to ensure in your plugin: - -- In your plugin's `kibana.json` plugin, add `"infra"` to `requiredPlugins`. -- The component needs to be mounted inside the hiearchy of a [`kibana-react` provider](https://github.com/elastic/kibana/blob/b2d0aa7b7fae1c89c8f9e8854ae73e71be64e765/src/plugins/kibana_react/README.md#L45). - -## Usage - -The simplest way to use the component is with a date range, passed with the `startTimestamp` and `endTimestamp` props. - -```tsx -const endTimestamp = Date.now(); -const startTimestamp = endTimestamp - 15 * 60 * 1000; // 15 minutes - -; -``` - -This will show a list of log entries between the time range, in ascending order (oldest first), but with the scroll position all the way to the bottom (showing the newest entries) - -### Filtering data - -You might want to show specific data for the purpose of your plugin. Maybe you want to show log lines from a specific host, or for an APM trace. You can pass a KQL expression via the `query` prop. - -```tsx - -``` - -### Modifying rendering - -By default the component will initially load at the bottom of the list, showing the newest entries. You can change what log line is shown in the center via the `center` prop. The prop takes a [`LogEntriesCursor`](https://github.com/elastic/kibana/blob/0a6c748cc837c016901f69ff05d81395aa2d41c8/x-pack/plugins/infra/common/http_api/log_entries/common.ts#L9-L13). - -```tsx - -``` - -If you want to highlight a specific log line, you can do so by passing its ID in the `highlight` prop. - -```tsx - -``` - -### Source configuration - -The infra plugin has the concept of "source configuration" to store settings for the logs UI. The component will use the source configuration to determine which indices to query or what columns to show. - -By default the `` uses the `"default"` source confiuration, but if your plugin uses a different one you can specify it via the `sourceId` prop. - -```tsx - -``` - -### Custom columns - -It is possible to change what columns are loaded without creating a whole new source configuration. To do so the component supports the `columns` prop. The default configuration can be replicated as follows. - -```tsx - -``` - -There are three column types: - - - - - -
`type: "timestamp"` - The configured timestamp field. Defaults to `@timestamp`. -
`type: "message"` - The value of the `message` field if it exists. If it doesn't, the component will try to recompose the original log line using values of other fields. -
`type: "field"` - A specific field specified in the `field` property. -
- -### Custom column rendering - -Besides customizing what columns are shown, you can also customize how a column is rendered. You can customize the width of the column, the text of the header, and how each value is rendered within the cell - -#### `width` option - -The `width` modifies the width of the column. It can be a number (in pixels) or a string with a valid CSS value. - -```tsx - -``` - -#### `header` option - -The `header` takes either a `boolean` value that specifies if the header should be rendered or not, or a `string` with the text to render. - -```tsx - -``` - -The default is `true`, which render the default values for each column type: - -| Column type | Default value | -| ----------- | ------------------------------------- | -| `timestamp` | Date of the top-most visible log line | -| `message` | `"Message"` literal | -| `field` | Field name | - -#### `render` option - -The `render` takes a function to customize the rendering of the column. The first argument is the value of the column. The function must return a valid `ReactNode`. - -```tsx - {new Date(timestamp).toString()}; }, - { type: 'field', field: 'log.level', render: (value) => value === 'warn' ? '⚠️' : 'ℹ️' } - { type: 'message', render: (message) => message.toUpperCase() } - ]} -/> -``` - -The first argument's type depends on the column type. - -| Column type | Type of the `value` | -| ----------- | ---------------------------------------------------------------------- | -| `timestamp` | `number`. The epoch_millis of the log line | -| `message` | `string`. The processed log message | -| `field` | `JsonValue`. The type of the field itself. Must be checked at runtime. | - -### Considerations - -As mentioned in the prerequisites, the component relies on `kibana-react` to access kibana's core services. If this is not the case the component will throw an exception when rendering. We advise to use an `` in your component hierarchy to catch this error if necessary. diff --git a/x-pack/plugins/infra/public/components/log_stream/log_stream.stories.mdx b/x-pack/plugins/infra/public/components/log_stream/log_stream.stories.mdx new file mode 100644 index 0000000000000..d579432c6291f --- /dev/null +++ b/x-pack/plugins/infra/public/components/log_stream/log_stream.stories.mdx @@ -0,0 +1,348 @@ +import { Meta, Story, Canvas, ArgsTable } from '@storybook/addon-docs/blocks'; +import { Subject } from 'rxjs'; + +import { I18nProvider } from '@kbn/i18n/react'; +import { EuiThemeProvider } from '../../../../observability/public'; +import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public'; + +import { DEFAULT_SOURCE_CONFIGURATION } from '../../test_utils/source_configuration'; +import { generateFakeEntries, ENTRIES_EMPTY } from '../../test_utils/entries'; + +import { LogStream } from './'; + + + +export const startTimestamp = 1595145600000; +export const endTimestamp = startTimestamp + 15 * 60 * 1000; + +export const fetch = function (url, params) { + switch (url) { + case '/api/infra/log_source_configurations/default': + return DEFAULT_SOURCE_CONFIGURATION; + case '/api/log_entries/entries': + const body = JSON.parse(params.body); + if (body.after?.time === body.endTimestamp || body.before?.time === body.startTimestamp) { + return ENTRIES_EMPTY; + } else { + const entries = generateFakeEntries( + 200, + body.startTimestamp, + body.endTimestamp, + body.columns || DEFAULT_SOURCE_CONFIGURATION.data.configuration.logColumns + ); + return { + data: { + entries, + topCursor: entries[0].cursor, + bottomCursor: entries[entries.length - 1].cursor, + hasMoreBefore: false, + }, + }; + } + default: + return {}; + } +}; + +export const uiSettings = { + get: (setting) => { + switch (setting) { + case 'dateFormat': + return 'MMM D, YYYY @ HH:mm:ss.SSS'; + case 'dateFormat:scaled': + return [['', 'HH:mm:ss.SSS']]; + } + }, + get$: () => { + return new Subject(); + }, +}; + +export const Template = (args) => ; + + ( + + + + {story()} + + + + ), + ]} +/> + +# Embeddable `` component + +The purpose of this component is to allow you, the developer, to have your very own Log Stream in your plugin. + +The component is exposed through `infra/public`. Since Kibana uses relative paths is up to you to find how to import it (sorry). + +```tsx +import { LogStream } from '../../../../../../infra/public'; +// ^^ Modify appropriately +``` + +## Prerequisites + +To use the component your plugin needs to follow certain criteria: + +- Ensure `"infra"` is specified as a `requiredPlugins` in your plugin's `kibana.json`. +- Ensure the `` component is mounted inside the hiearchy of a [`kibana-react` provider](https://github.com/elastic/kibana/blob/b2d0aa7b7fae1c89c8f9e8854ae73e71be64e765/src/plugins/kibana_react/README.md#L45). + +## Usage + +The simplest way to use the component is with a date range + +```tsx +const endTimestamp = Date.now(); +const startTimestamp = endTimestamp - 15 * 60 * 1000; // 15 minutes + +; +``` + +This will show a list of log entries between the specified timestamps. + + + + {Template.bind({})} + + + +## Query log entries + +You might want to show specific log entries in your plugin. Maybe you want to show log lines from a specific host, or for an AMP trace. The component has a `query` prop that accepts valid KQL expressions. + +```tsx + +``` + +## Center the view on a specific entry + +By default the component will load at the bottom of the list, showing the newest entries. You can change the rendering point with the `center` prop. The prop takes a [`LogEntriesCursor`](https://github.com/elastic/kibana/blob/0a6c748cc837c016901f69ff05d81395aa2d41c8/x-pack/plugins/infra/common/http_api/log_entries/common.ts#L9-L13). + +```tsx + +``` + + + + {Template.bind({})} + + + +## Highlight a specific entry + +The component can highlight a specific line via the `highlight` prop. It takes the `id` of the log entry. Note that this prop doesn't center the view around that log line. + +```tsx + +``` + + + + {Template.bind({})} + + + +## Column configuration + +By default the component will use the same columns as the Logs UI: + +- `@timestamp` of the log. +- `event.dataset` field. +- The log message. This might be the `message` field, or a reconstruction based on other fields. + +These columns are user-configurable. When the end user changes the default columns those changes will be reflected in the `` component. + +If the default columns don't work for the use case of your plugin, or you don't want your plugin to be affected by user changes, you can specify which columns you want. We offer two mechanisms for this. + +### With a `columns` prop + +The easiest way is to specify what columns you want with the `columns` prop. + +```tsx + +``` + + + + {Template.bind({})} + + + +The rendering of the column headers and the cell contents can also be customized with the following properties: + + + + + + + + + + + + + + + + + + + +
+ width + + number | string + The width of the column. Accepts any valid `flex-basis` value.
+ header + + boolean | string +
+ Defaults to true +
+ When `boolean`, decide if the header should render or not. +
+ When `string`, show the string contents in the header. +
+ render + + (timestamp: number) => ReactNode for the `timestamp` column +
+ (message: string) => ReactNode for the `message` column. +
+ (value: JsonValue) => ReactNode for the `field` columns. +
How should the column value render
+ +```tsx + { + switch (value) { + case 'debug': + return '🐞'; + case 'info': + return 'ℹ️'; + case 'warn': + return '⚠️'; + case 'error': + return '❌'; + } + }, + }, + { type: 'message' }, + ]} +/> +``` + + + { + switch (value) { + case 'debug': + return '🐞'; + case 'info': + return 'ℹ️'; + case 'warn': + return '⚠️'; + case 'error': + return '❌'; + } + }, + }, + { type: 'message' }, + ], + }} + > + {Template.bind({})} + + + +### With a source configuration + +The infra plugin has the concept of a "source configuration", a collection of settings that apply to the logs and metrics UIs. The component uses the source configuration to determine which indices to query or what columns to show. + +The `` component will use the `"default"` source configuration. If you want to use your own configuration, you need to first create it when you initialize your plugin, and then specify it in the `` component with the `sourceId` prop. + +```tsx +// Your `plugin/init.ts` +class MyPlugin { + // ... + setup(core, plugins) { + plugins.infra.defineInternalSourceConfiguration( + 'my_source', // ID for your source configuration + { + logAlias: 'some-index-*', // Optional. what ES index to query. + logColumns: [ + { timestampColumn: { id: '...uuid4' }, // The `@timestamp` column. + { fieldColumn: { id: '...uuid4', field: 'some_field' }}, // Any column(s) you want. + { messageColumn: { id: '...uuid' }} // The `message` column. + ] + } + ); + } +} + +// Somewhere else on your code + +``` diff --git a/x-pack/plugins/infra/public/test_utils/entries.ts b/x-pack/plugins/infra/public/test_utils/entries.ts new file mode 100644 index 0000000000000..04c87d5f73902 --- /dev/null +++ b/x-pack/plugins/infra/public/test_utils/entries.ts @@ -0,0 +1,73 @@ +/* + * 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 faker from 'faker'; +import { LogEntry } from '../../common/http_api'; +import { LogSourceConfiguration } from '../containers/logs/log_source'; + +export const ENTRIES_EMPTY = { + data: { + entries: [], + topCursor: null, + bottomCursor: null, + }, +}; + +export function generateFakeEntries( + count: number, + startTimestamp: number, + endTimestamp: number, + columns: LogSourceConfiguration['configuration']['logColumns'] +): LogEntry[] { + const entries: LogEntry[] = []; + const timestampStep = Math.floor((endTimestamp - startTimestamp) / count); + for (let i = 0; i < count; i++) { + const timestamp = i === count - 1 ? endTimestamp : startTimestamp + timestampStep * i; + entries.push({ + id: `entry-${i}`, + context: {}, + cursor: { time: timestamp, tiebreaker: i }, + columns: columns.map((column) => { + if ('timestampColumn' in column) { + return { columnId: column.timestampColumn.id, timestamp }; + } else if ('messageColumn' in column) { + return { + columnId: column.messageColumn.id, + message: [{ field: 'message', value: [fakeColumnValue('message')], highlights: [] }], + }; + } else { + return { + columnId: column.fieldColumn.id, + field: column.fieldColumn.field, + value: [fakeColumnValue(column.fieldColumn.field)], + highlights: [], + }; + } + }), + }); + } + + return entries; +} + +function fakeColumnValue(field: string): string { + switch (field) { + case 'message': + return faker.fake( + '{{internet.ip}} - [{{date.past}}] "GET {{internet.url}} HTTP/1.1" 200 {{random.number}} "-" "{{internet.userAgent}}"' + ); + case 'event.dataset': + return faker.fake('{{hacker.noun}}.{{hacker.noun}}'); + case 'log.file.path': + return faker.system.filePath(); + case 'log.level': + return faker.random.arrayElement(['debug', 'info', 'warn', 'error']); + case 'host.name': + return faker.hacker.noun(); + default: + return faker.lorem.sentence(); + } +} diff --git a/x-pack/plugins/infra/public/test_utils/source_configuration.ts b/x-pack/plugins/infra/public/test_utils/source_configuration.ts new file mode 100644 index 0000000000000..7c266d1f4ab6b --- /dev/null +++ b/x-pack/plugins/infra/public/test_utils/source_configuration.ts @@ -0,0 +1,46 @@ +/* + * 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 { GetLogSourceConfigurationSuccessResponsePayload } from '../../common/http_api/log_sources'; + +export const DEFAULT_SOURCE_CONFIGURATION: GetLogSourceConfigurationSuccessResponsePayload = { + data: { + id: 'default', + version: 'WzQwNiwxXQ==', + updatedAt: 1608559663482, + origin: 'stored', + configuration: { + name: 'Default', + description: '', + logAlias: 'kibana_sample_data_logs*', + fields: { + container: 'container.id', + host: 'host.name', + pod: 'kubernetes.pod.uid', + tiebreaker: '_doc', + timestamp: '@timestamp', + }, + logColumns: [ + { + timestampColumn: { + id: '5e7f964a-be8a-40d8-88d2-fbcfbdca0e2f', + }, + }, + { + fieldColumn: { + id: ' eb9777a8-fcd3-420e-ba7d-172fff6da7a2', + field: 'event.dataset', + }, + }, + { + messageColumn: { + id: 'b645d6da-824b-4723-9a2a-e8cece1645c0', + }, + }, + ], + }, + }, +}; diff --git a/yarn.lock b/yarn.lock index 4c4a2f1ffc3dd..02bd107ea0e65 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4775,6 +4775,11 @@ resolved "https://registry.yarnpkg.com/@types/extract-zip/-/extract-zip-1.6.2.tgz#5c7eb441c41136167a42b88b64051e6260c29e86" integrity sha1-XH60QcQRNhZ6QriLZAUeYmDCnoY= +"@types/faker@^5.1.5": + version "5.1.5" + resolved "https://registry.yarnpkg.com/@types/faker/-/faker-5.1.5.tgz#f14b015e0100232bb00c6dd7611505efb08709a0" + integrity sha512-2uEQFb7bsx68rqD4F8q95wZq6LTLOyexjv6BnvJogCO4jStkyc6IDEkODPQcWfovI6g6M3uPQ2/uD/oedJKkNw== + "@types/fancy-log@^1.3.1": version "1.3.1" resolved "https://registry.yarnpkg.com/@types/fancy-log/-/fancy-log-1.3.1.tgz#dd94fbc8c2e2ab8ab402ca8d04bb8c34965f0696" @@ -13369,10 +13374,10 @@ extsprintf@1.3.0, extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= -faker@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/faker/-/faker-1.1.0.tgz#230738ebd37edad9de4a421de12922bd8206a872" - integrity sha1-Iwc469N+2tneSkId4SkivYIGqHI= +faker@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/faker/-/faker-5.1.0.tgz#e10fa1dec4502551aee0eb771617a7e7b94692e8" + integrity sha512-RrWKFSSA/aNLP0g3o2WW1Zez7/MnMr7xkiZmoCfAGZmdkDQZ6l2KtuXHN5XjdvpRjDl8+3vf+Rrtl06Z352+Mw== fancy-log@^1.3.2: version "1.3.2" From 78dea4f03f227e60100214119bf9133c65d3a3e4 Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Tue, 12 Jan 2021 08:40:10 -0800 Subject: [PATCH 44/64] Use documentation link service for security links (#87409) --- src/core/public/doc_links/doc_links_service.ts | 4 ++++ .../license_management/public/plugin.ts | 4 +--- .../api_keys_grid_page.test.tsx.snap | 3 ++- .../api_keys/api_keys_management_app.test.tsx | 2 +- .../management/api_keys/documentation_links.ts | 10 ++++++---- .../role_mappings/documentation_links.ts | 18 ++++++++++++------ .../role_mappings_management_app.test.tsx | 6 +++--- .../management/roles/documentation_links.ts | 14 +++++++++----- .../roles/roles_management_app.test.tsx | 6 +++--- .../security_checkup/documentation_links.ts | 6 +++--- .../spaces/public/lib/documentation_links.ts | 6 +++--- 11 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index 12266ec8de2e4..43960ce7db467 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -201,10 +201,13 @@ export class DocLinksService { apiKeyServiceSettings: `${ELASTICSEARCH_DOCS}security-settings.html#api-key-service-settings`, clusterPrivileges: `${ELASTICSEARCH_DOCS}security-privileges.html#privileges-list-cluster`, elasticsearchSettings: `${ELASTICSEARCH_DOCS}security-settings.html`, + elasticsearchEnableSecurity: `${ELASTICSEARCH_DOCS}get-started-enable-security.html`, indicesPrivileges: `${ELASTICSEARCH_DOCS}security-privileges.html#privileges-list-indices`, kibanaTLS: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/configuring-tls.html`, kibanaPrivileges: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/kibana-privileges.html`, mappingRoles: `${ELASTICSEARCH_DOCS}mapping-roles.html`, + mappingRolesFieldRules: `${ELASTICSEARCH_DOCS}role-mapping-resources.html#mapping-roles-rule-field`, + runAsPrivilege: `${ELASTICSEARCH_DOCS}security-privileges.html#_run_as_privilege`, }, watcher: { jiraAction: `${ELASTICSEARCH_DOCS}actions-jira.html`, @@ -219,6 +222,7 @@ export class DocLinksService { createIndex: `${ELASTICSEARCH_DOCS}indices-create-index.html`, createSnapshotLifecylePolicy: `${ELASTICSEARCH_DOCS}slm-api-put-policy.html`, createRoleMapping: `${ELASTICSEARCH_DOCS}security-api-put-role-mapping.html`, + createRoleMappingTemplates: `${ELASTICSEARCH_DOCS}security-api-put-role-mapping.html#_role_templates`, createApiKey: `${ELASTICSEARCH_DOCS}security-api-create-api-key.html`, createPipeline: `${ELASTICSEARCH_DOCS}put-pipeline-api.html`, createTransformRequest: `${ELASTICSEARCH_DOCS}put-transform.html#put-transform-request-body`, diff --git a/x-pack/plugins/license_management/public/plugin.ts b/x-pack/plugins/license_management/public/plugin.ts index 27e31726f9a19..675945def7979 100644 --- a/x-pack/plugins/license_management/public/plugin.ts +++ b/x-pack/plugins/license_management/public/plugin.ts @@ -63,10 +63,8 @@ export class LicenseManagementUIPlugin docLinks, chrome: { docTitle }, } = coreStart; - const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = docLinks; - const esBase = `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}`; const appDocLinks = { - security: `${esBase}/security-settings.html`, + security: docLinks.links.security.elasticsearchSettings, }; docTitle.change(PLUGIN.title); diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/__snapshots__/api_keys_grid_page.test.tsx.snap b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/__snapshots__/api_keys_grid_page.test.tsx.snap index 8966acee95c5d..3c6458a6d2467 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/__snapshots__/api_keys_grid_page.test.tsx.snap +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/__snapshots__/api_keys_grid_page.test.tsx.snap @@ -4,7 +4,8 @@ exports[`APIKeysGridPage renders a callout when API keys are not enabled 1`] = ` diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.test.tsx b/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.test.tsx index ca370271b4360..2b43bc7ebc20d 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.test.tsx +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.test.tsx @@ -43,7 +43,7 @@ describe('apiKeysManagementApp', () => { expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: '/', text: 'API Keys' }]); expect(container).toMatchInlineSnapshot(`
- Page: {"notifications":{"toasts":{}},"docLinks":{"esDocBasePath":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/"},"apiKeysAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}}} + Page: {"notifications":{"toasts":{}},"docLinks":{"apiKeySettings":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-settings.html#api-key-service-settings","createApiKey":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-api-create-api-key.html"},"apiKeysAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}}}
`); diff --git a/x-pack/plugins/security/public/management/api_keys/documentation_links.ts b/x-pack/plugins/security/public/management/api_keys/documentation_links.ts index 4165c2a2372c9..66a54f1cb7b72 100644 --- a/x-pack/plugins/security/public/management/api_keys/documentation_links.ts +++ b/x-pack/plugins/security/public/management/api_keys/documentation_links.ts @@ -7,17 +7,19 @@ import { DocLinksStart } from 'src/core/public'; export class DocumentationLinksService { - private readonly esDocBasePath: string; + private readonly apiKeySettings: string; + private readonly createApiKey: string; constructor(docLinks: DocLinksStart) { - this.esDocBasePath = `${docLinks.ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${docLinks.DOC_LINK_VERSION}/`; + this.apiKeySettings = `${docLinks.links.security.apiKeyServiceSettings}`; + this.createApiKey = `${docLinks.links.apis.createApiKey}`; } public getApiKeyServiceSettingsDocUrl() { - return `${this.esDocBasePath}security-settings.html#api-key-service-settings`; + return `${this.apiKeySettings}`; } public getCreateApiKeyDocUrl() { - return `${this.esDocBasePath}security-api-create-api-key.html`; + return `${this.createApiKey}`; } } diff --git a/x-pack/plugins/security/public/management/role_mappings/documentation_links.ts b/x-pack/plugins/security/public/management/role_mappings/documentation_links.ts index fb4b4b00cef7d..2098d5c71ee7a 100644 --- a/x-pack/plugins/security/public/management/role_mappings/documentation_links.ts +++ b/x-pack/plugins/security/public/management/role_mappings/documentation_links.ts @@ -7,25 +7,31 @@ import { DocLinksStart } from 'src/core/public'; export class DocumentationLinksService { - private readonly esDocBasePath: string; + private readonly mappingRoles: string; + private readonly createRoleMapping: string; + private readonly createRoleMappingTemplates: string; + private readonly roleMappingFieldRules: string; constructor(docLinks: DocLinksStart) { - this.esDocBasePath = `${docLinks.ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${docLinks.DOC_LINK_VERSION}/`; + this.mappingRoles = `${docLinks.links.security.mappingRoles}`; + this.createRoleMapping = `${docLinks.links.apis.createRoleMapping}`; + this.createRoleMappingTemplates = `${docLinks.links.apis.createRoleMappingTemplates}`; + this.roleMappingFieldRules = `${docLinks.links.security.mappingRolesFieldRules}`; } public getRoleMappingDocUrl() { - return `${this.esDocBasePath}/mapping-roles.html`; + return `${this.mappingRoles}`; } public getRoleMappingAPIDocUrl() { - return `${this.esDocBasePath}/security-api-put-role-mapping.html`; + return `${this.createRoleMapping}`; } public getRoleMappingTemplateDocUrl() { - return `${this.esDocBasePath}/security-api-put-role-mapping.html#_role_templates`; + return `${this.createRoleMappingTemplates}`; } public getRoleMappingFieldRulesDocUrl() { - return `${this.esDocBasePath}/role-mapping-resources.html#mapping-roles-rule-field`; + return `${this.roleMappingFieldRules}`; } } diff --git a/x-pack/plugins/security/public/management/role_mappings/role_mappings_management_app.test.tsx b/x-pack/plugins/security/public/management/role_mappings/role_mappings_management_app.test.tsx index 4ce49501a3ed1..c72aeac5ba6f2 100644 --- a/x-pack/plugins/security/public/management/role_mappings/role_mappings_management_app.test.tsx +++ b/x-pack/plugins/security/public/management/role_mappings/role_mappings_management_app.test.tsx @@ -54,7 +54,7 @@ describe('roleMappingsManagementApp', () => { expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: `/`, text: 'Role Mappings' }]); expect(container).toMatchInlineSnapshot(`
- Role Mappings Page: {"notifications":{"toasts":{}},"rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"roleMappingsAPI":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"docLinks":{"esDocBasePath":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/"},"history":{"action":"PUSH","length":1,"location":{"pathname":"/","search":"","hash":""}}} + Role Mappings Page: {"notifications":{"toasts":{}},"rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"roleMappingsAPI":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"docLinks":{"mappingRoles":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/mapping-roles.html","createRoleMapping":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-api-put-role-mapping.html","createRoleMappingTemplates":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-api-put-role-mapping.html#_role_templates","roleMappingFieldRules":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/role-mapping-resources.html#mapping-roles-rule-field"},"history":{"action":"PUSH","length":1,"location":{"pathname":"/","search":"","hash":""}}}
`); @@ -73,7 +73,7 @@ describe('roleMappingsManagementApp', () => { ]); expect(container).toMatchInlineSnapshot(`
- Role Mapping Edit Page: {"roleMappingsAPI":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"notifications":{"toasts":{}},"docLinks":{"esDocBasePath":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/"},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit","search":"","hash":""}}} + Role Mapping Edit Page: {"roleMappingsAPI":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"notifications":{"toasts":{}},"docLinks":{"mappingRoles":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/mapping-roles.html","createRoleMapping":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-api-put-role-mapping.html","createRoleMappingTemplates":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-api-put-role-mapping.html#_role_templates","roleMappingFieldRules":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/role-mapping-resources.html#mapping-roles-rule-field"},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit","search":"","hash":""}}}
`); @@ -94,7 +94,7 @@ describe('roleMappingsManagementApp', () => { ]); expect(container).toMatchInlineSnapshot(`
- Role Mapping Edit Page: {"name":"role@mapping","roleMappingsAPI":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"notifications":{"toasts":{}},"docLinks":{"esDocBasePath":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/"},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit/role@mapping","search":"","hash":""}}} + Role Mapping Edit Page: {"name":"role@mapping","roleMappingsAPI":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"notifications":{"toasts":{}},"docLinks":{"mappingRoles":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/mapping-roles.html","createRoleMapping":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-api-put-role-mapping.html","createRoleMappingTemplates":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-api-put-role-mapping.html#_role_templates","roleMappingFieldRules":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/role-mapping-resources.html#mapping-roles-rule-field"},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit/role@mapping","search":"","hash":""}}}
`); diff --git a/x-pack/plugins/security/public/management/roles/documentation_links.ts b/x-pack/plugins/security/public/management/roles/documentation_links.ts index cf46973d3541c..aa19fbecb9c7b 100644 --- a/x-pack/plugins/security/public/management/roles/documentation_links.ts +++ b/x-pack/plugins/security/public/management/roles/documentation_links.ts @@ -7,21 +7,25 @@ import { DocLinksStart } from 'src/core/public'; export class DocumentationLinksService { - private readonly esDocBasePath: string; + private readonly esClusterPrivileges: string; + private readonly esRunAsPrivilege: string; + private readonly esIndicesPrivileges: string; constructor(docLinks: DocLinksStart) { - this.esDocBasePath = `${docLinks.ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${docLinks.DOC_LINK_VERSION}/`; + this.esClusterPrivileges = `${docLinks.links.security.clusterPrivileges}`; + this.esRunAsPrivilege = `${docLinks.links.security.runAsPrivilege}`; + this.esIndicesPrivileges = `${docLinks.links.security.indicesPrivileges}`; } public getESClusterPrivilegesDocUrl() { - return `${this.esDocBasePath}security-privileges.html#privileges-list-cluster`; + return `${this.esClusterPrivileges}`; } public getESRunAsPrivilegesDocUrl() { - return `${this.esDocBasePath}security-privileges.html#_run_as_privilege`; + return `${this.esRunAsPrivilege}`; } public getESIndicesPrivilegesDocUrl() { - return `${this.esDocBasePath}security-privileges.html#privileges-list-indices`; + return `${this.esIndicesPrivileges}`; } } diff --git a/x-pack/plugins/security/public/management/roles/roles_management_app.test.tsx b/x-pack/plugins/security/public/management/roles/roles_management_app.test.tsx index 5e25cf8581f6e..8003b21f5d906 100644 --- a/x-pack/plugins/security/public/management/roles/roles_management_app.test.tsx +++ b/x-pack/plugins/security/public/management/roles/roles_management_app.test.tsx @@ -87,7 +87,7 @@ describe('rolesManagementApp', () => { expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: `/`, text: 'Roles' }, { text: 'Create' }]); expect(container).toMatchInlineSnapshot(`
- Role Edit Page: {"action":"edit","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{"esDocBasePath":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/"},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit","search":"","hash":""}}} + Role Edit Page: {"action":"edit","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{"esClusterPrivileges":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#privileges-list-cluster","esRunAsPrivilege":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#_run_as_privilege","esIndicesPrivileges":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#privileges-list-indices"},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit","search":"","hash":""}}}
`); @@ -108,7 +108,7 @@ describe('rolesManagementApp', () => { ]); expect(container).toMatchInlineSnapshot(`
- Role Edit Page: {"action":"edit","roleName":"role@name","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{"esDocBasePath":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/"},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit/role@name","search":"","hash":""}}} + Role Edit Page: {"action":"edit","roleName":"role@name","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{"esClusterPrivileges":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#privileges-list-cluster","esRunAsPrivilege":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#_run_as_privilege","esIndicesPrivileges":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#privileges-list-indices"},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit/role@name","search":"","hash":""}}}
`); @@ -126,7 +126,7 @@ describe('rolesManagementApp', () => { expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: `/`, text: 'Roles' }, { text: 'Create' }]); expect(container).toMatchInlineSnapshot(`
- Role Edit Page: {"action":"clone","roleName":"someRoleName","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{"esDocBasePath":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/"},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/clone/someRoleName","search":"","hash":""}}} + Role Edit Page: {"action":"clone","roleName":"someRoleName","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{"esClusterPrivileges":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#privileges-list-cluster","esRunAsPrivilege":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#_run_as_privilege","esIndicesPrivileges":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#privileges-list-indices"},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/clone/someRoleName","search":"","hash":""}}}
`); diff --git a/x-pack/plugins/security/public/security_checkup/documentation_links.ts b/x-pack/plugins/security/public/security_checkup/documentation_links.ts index b53a6ffd94be0..4a2a2bc968cc6 100644 --- a/x-pack/plugins/security/public/security_checkup/documentation_links.ts +++ b/x-pack/plugins/security/public/security_checkup/documentation_links.ts @@ -7,13 +7,13 @@ import { DocLinksStart } from 'src/core/public'; export class DocumentationLinksService { - private readonly esDocBasePath: string; + private readonly esEnableSecurity: string; constructor(docLinks: DocLinksStart) { - this.esDocBasePath = `${docLinks.ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${docLinks.DOC_LINK_VERSION}`; + this.esEnableSecurity = `${docLinks.links.security.elasticsearchEnableSecurity}`; } public getEnableSecurityDocUrl() { - return `${this.esDocBasePath}/get-started-enable-security.html?blade=kibanasecuritymessage`; + return `${this.esEnableSecurity}?blade=kibanasecuritymessage`; } } diff --git a/x-pack/plugins/spaces/public/lib/documentation_links.ts b/x-pack/plugins/spaces/public/lib/documentation_links.ts index 71ba89d5b87e2..1d6a6886b6ad6 100644 --- a/x-pack/plugins/spaces/public/lib/documentation_links.ts +++ b/x-pack/plugins/spaces/public/lib/documentation_links.ts @@ -7,13 +7,13 @@ import { DocLinksStart } from 'src/core/public'; export class DocumentationLinksService { - private readonly kbn: string; + private readonly kbnPrivileges: string; constructor(docLinks: DocLinksStart) { - this.kbn = `${docLinks.ELASTIC_WEBSITE_URL}guide/en/kibana/${docLinks.DOC_LINK_VERSION}/`; + this.kbnPrivileges = `${docLinks.links.security.kibanaPrivileges}`; } public getKibanaPrivilegesDocUrl() { - return `${this.kbn}kibana-privileges.html`; + return `${this.kbnPrivileges}`; } } From 86d53b683ec30afb14ef983daea605bf0707e425 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Tue, 12 Jan 2021 17:45:37 +0100 Subject: [PATCH 45/64] [Search Sessions][Discover] Send to background integration improvements and fixes (#87311) --- .../public/application/angular/discover.js | 2 +- .../angular/discover_state.test.ts | 35 ++++++++++++++++++- .../application/angular/discover_state.ts | 27 +++++++++++--- .../discover/public/url_generator.test.ts | 2 +- src/plugins/discover/public/url_generator.ts | 2 +- x-pack/test/functional/apps/discover/index.ts | 1 - .../tests}/apps/discover/async_search.ts | 7 ++-- .../tests/apps/discover/index.ts | 1 + 8 files changed, 64 insertions(+), 13 deletions(-) rename x-pack/test/{functional => send_search_to_background_integration/tests}/apps/discover/async_search.ts (88%) diff --git a/src/plugins/discover/public/application/angular/discover.js b/src/plugins/discover/public/application/angular/discover.js index 4c5cb864b5111..839add1aeb22d 100644 --- a/src/plugins/discover/public/application/angular/discover.js +++ b/src/plugins/discover/public/application/angular/discover.js @@ -295,7 +295,7 @@ function discoverController($element, $route, $scope, $timeout, Promise, uiCapab createSearchSessionRestorationDataProvider({ appStateContainer, data, - getSavedSearchId: () => savedSearch.id, + getSavedSearch: () => savedSearch, }) ); diff --git a/src/plugins/discover/public/application/angular/discover_state.test.ts b/src/plugins/discover/public/application/angular/discover_state.test.ts index 2914ce8f17a09..e05a3028c5ca9 100644 --- a/src/plugins/discover/public/application/angular/discover_state.test.ts +++ b/src/plugins/discover/public/application/angular/discover_state.test.ts @@ -17,8 +17,14 @@ * under the License. */ -import { getState, GetStateReturn } from './discover_state'; +import { + getState, + GetStateReturn, + createSearchSessionRestorationDataProvider, +} from './discover_state'; import { createBrowserHistory, History } from 'history'; +import { dataPluginMock } from '../../../../data/public/mocks'; +import { SavedSearch } from '../../saved_searches'; let history: History; let state: GetStateReturn; @@ -103,3 +109,30 @@ describe('Test discover state with legacy migration', () => { `); }); }); + +describe('createSearchSessionRestorationDataProvider', () => { + let mockSavedSearch: SavedSearch = ({} as unknown) as SavedSearch; + const searchSessionInfoProvider = createSearchSessionRestorationDataProvider({ + data: dataPluginMock.createStartContract(), + appStateContainer: getState({ + history: createBrowserHistory(), + }).appStateContainer, + getSavedSearch: () => mockSavedSearch, + }); + + describe('session name', () => { + test('No saved search returns default name', async () => { + expect(await searchSessionInfoProvider.getName()).toBe('Discover'); + }); + + test('Saved Search with a title returns saved search title', async () => { + mockSavedSearch = ({ id: 'id', title: 'Name' } as unknown) as SavedSearch; + expect(await searchSessionInfoProvider.getName()).toBe('Name'); + }); + + test('Saved Search without a title returns default name', async () => { + mockSavedSearch = ({ id: 'id', title: undefined } as unknown) as SavedSearch; + expect(await searchSessionInfoProvider.getName()).toBe('Discover'); + }); + }); +}); diff --git a/src/plugins/discover/public/application/angular/discover_state.ts b/src/plugins/discover/public/application/angular/discover_state.ts index 9bf3cc587a3d8..69291872fa855 100644 --- a/src/plugins/discover/public/application/angular/discover_state.ts +++ b/src/plugins/discover/public/application/angular/discover_state.ts @@ -17,6 +17,7 @@ * under the License. */ import { isEqual } from 'lodash'; +import { i18n } from '@kbn/i18n'; import { History } from 'history'; import { NotificationsStart } from 'kibana/public'; import { @@ -38,6 +39,7 @@ import { import { migrateLegacyQuery } from '../helpers/migrate_legacy_query'; import { DiscoverGridSettings } from '../components/discover_grid/types'; import { DISCOVER_APP_URL_GENERATOR, DiscoverUrlGeneratorState } from '../../url_generator'; +import { SavedSearch } from '../../saved_searches'; export interface AppState { /** @@ -264,15 +266,32 @@ export function isEqualState(stateA: AppState, stateB: AppState) { export function createSearchSessionRestorationDataProvider(deps: { appStateContainer: StateContainer; data: DataPublicPluginStart; - getSavedSearchId: () => string | undefined; + getSavedSearch: () => SavedSearch; }): SearchSessionInfoProvider { + const getSavedSearchId = () => deps.getSavedSearch().id; return { - getName: async () => 'Discover', + getName: async () => { + const savedSearch = deps.getSavedSearch(); + return ( + (savedSearch.id && savedSearch.title) || + i18n.translate('discover.discoverDefaultSearchSessionName', { + defaultMessage: 'Discover', + }) + ); + }, getUrlGeneratorData: async () => { return { urlGeneratorId: DISCOVER_APP_URL_GENERATOR, - initialState: createUrlGeneratorState({ ...deps, forceAbsoluteTime: false }), - restoreState: createUrlGeneratorState({ ...deps, forceAbsoluteTime: true }), + initialState: createUrlGeneratorState({ + ...deps, + getSavedSearchId, + forceAbsoluteTime: false, + }), + restoreState: createUrlGeneratorState({ + ...deps, + getSavedSearchId, + forceAbsoluteTime: true, + }), }; }, }; diff --git a/src/plugins/discover/public/url_generator.test.ts b/src/plugins/discover/public/url_generator.test.ts index 95bff6b1fdc9c..f87ef4f91108a 100644 --- a/src/plugins/discover/public/url_generator.test.ts +++ b/src/plugins/discover/public/url_generator.test.ts @@ -62,7 +62,7 @@ describe('Discover url generator', () => { const url = await generator.createUrl({ savedSearchId }); const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']); - expect(url.startsWith(`${appBasePath}#/${savedSearchId}`)).toBe(true); + expect(url.startsWith(`${appBasePath}#/view/${savedSearchId}`)).toBe(true); expect(_a).toEqual({}); expect(_g).toEqual({}); }); diff --git a/src/plugins/discover/public/url_generator.ts b/src/plugins/discover/public/url_generator.ts index 6d86818910b11..d1b574c360d88 100644 --- a/src/plugins/discover/public/url_generator.ts +++ b/src/plugins/discover/public/url_generator.ts @@ -119,7 +119,7 @@ export class DiscoverUrlGenerator sort, interval, }: DiscoverUrlGeneratorState): Promise => { - const savedSearchPath = savedSearchId ? encodeURIComponent(savedSearchId) : ''; + const savedSearchPath = savedSearchId ? `view/${encodeURIComponent(savedSearchId)}` : ''; const appState: { query?: Query; filters?: Filter[]; diff --git a/x-pack/test/functional/apps/discover/index.ts b/x-pack/test/functional/apps/discover/index.ts index 13426da504bd9..57599c82d8de3 100644 --- a/x-pack/test/functional/apps/discover/index.ts +++ b/x-pack/test/functional/apps/discover/index.ts @@ -16,6 +16,5 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./error_handling')); loadTestFile(require.resolve('./visualize_field')); loadTestFile(require.resolve('./value_suggestions')); - loadTestFile(require.resolve('./async_search')); }); } diff --git a/x-pack/test/functional/apps/discover/async_search.ts b/x-pack/test/send_search_to_background_integration/tests/apps/discover/async_search.ts similarity index 88% rename from x-pack/test/functional/apps/discover/async_search.ts rename to x-pack/test/send_search_to_background_integration/tests/apps/discover/async_search.ts index 77d60f4036a3b..d64df98c98601 100644 --- a/x-pack/test/functional/apps/discover/async_search.ts +++ b/x-pack/test/send_search_to_background_integration/tests/apps/discover/async_search.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../ftr_provider_context'; +import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ getPageObjects, getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); @@ -31,14 +31,13 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(searchSessionId2).not.to.be(searchSessionId1); }); - // NOTE: this test will be revised when - // `searchSessionId` functionality actually works - it('search session id should be picked up from the URL', async () => { + it('search session id should be picked up from the URL, non existing session id errors out', async () => { const url = await browser.getCurrentUrl(); const fakeSearchSessionId = '__test__'; const savedSessionURL = url + `&searchSessionId=${fakeSearchSessionId}`; await browser.navigateTo(savedSessionURL); await PageObjects.header.waitUntilLoadingHasFinished(); + await testSubjects.existOrFail('discoverNoResultsError'); // expect error because of fake searchSessionId const searchSessionId1 = await getSearchSessionId(); expect(searchSessionId1).to.be(fakeSearchSessionId); await queryBar.clickQuerySubmitButton(); diff --git a/x-pack/test/send_search_to_background_integration/tests/apps/discover/index.ts b/x-pack/test/send_search_to_background_integration/tests/apps/discover/index.ts index b4fc74072ce00..d4f254e552dcd 100644 --- a/x-pack/test/send_search_to_background_integration/tests/apps/discover/index.ts +++ b/x-pack/test/send_search_to_background_integration/tests/apps/discover/index.ts @@ -17,6 +17,7 @@ export default function ({ loadTestFile, getService }: FtrProviderContext) { await kibanaServer.uiSettings.replace({ defaultIndex: 'logstash-*' }); }); + loadTestFile(require.resolve('./async_search')); loadTestFile(require.resolve('./sessions_in_space')); }); } From 04d4d8523da3c5007954affe264f376b3df841ce Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Tue, 12 Jan 2021 11:47:30 -0500 Subject: [PATCH 46/64] Use fetchClustersRange (#87882) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/monitoring/server/alerts/base_alert.ts | 2 +- .../monitoring/server/alerts/missing_monitoring_data_alert.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/monitoring/server/alerts/base_alert.ts b/x-pack/plugins/monitoring/server/alerts/base_alert.ts index 405518d5de378..2a5d956b04f7c 100644 --- a/x-pack/plugins/monitoring/server/alerts/base_alert.ts +++ b/x-pack/plugins/monitoring/server/alerts/base_alert.ts @@ -290,7 +290,7 @@ export class BaseAlert { ? { timestamp: { format: 'epoch_millis', - gte: limit - this.alertOptions.fetchClustersRange, + gte: +new Date() - limit - this.alertOptions.fetchClustersRange, }, } : undefined; diff --git a/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_alert.ts b/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_alert.ts index b4c8a667a1ce8..bf2ed341aac83 100644 --- a/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_alert.ts +++ b/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_alert.ts @@ -40,6 +40,7 @@ export class MissingMonitoringDataAlert extends BaseAlert { id: ALERT_MISSING_MONITORING_DATA, name: ALERT_DETAILS[ALERT_MISSING_MONITORING_DATA].label, accessorKey: 'gapDuration', + fetchClustersRange: LIMIT_BUFFER, defaultParams: { duration: '15m', limit: '1d', @@ -62,7 +63,6 @@ export class MissingMonitoringDataAlert extends BaseAlert { ], }); } - protected async fetchData( params: CommonAlertParams, callCluster: any, From fc994dfe978c9a00b5a7c97ed340479083eadce1 Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Tue, 12 Jan 2021 11:47:49 -0500 Subject: [PATCH 47/64] Update logstash files to ts where we read from source (#86787) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/monitoring/common/types/es.ts | 31 +++++++ .../{get_node_info.js => get_node_info.ts} | 29 ++++--- .../{get_pipeline.js => get_pipeline.ts} | 48 +++++++---- ...ment.js => get_pipeline_state_document.ts} | 20 +++-- ...eline_vertex.js => get_pipeline_vertex.ts} | 85 +++++++++++-------- 5 files changed, 146 insertions(+), 67 deletions(-) rename x-pack/plugins/monitoring/server/lib/logstash/{get_node_info.js => get_node_info.ts} (65%) rename x-pack/plugins/monitoring/server/lib/logstash/{get_pipeline.js => get_pipeline.ts} (78%) rename x-pack/plugins/monitoring/server/lib/logstash/{get_pipeline_state_document.js => get_pipeline_state_document.ts} (75%) rename x-pack/plugins/monitoring/server/lib/logstash/{get_pipeline_vertex.js => get_pipeline_vertex.ts} (73%) diff --git a/x-pack/plugins/monitoring/common/types/es.ts b/x-pack/plugins/monitoring/common/types/es.ts index 853e140ec66c7..725ff214ae795 100644 --- a/x-pack/plugins/monitoring/common/types/es.ts +++ b/x-pack/plugins/monitoring/common/types/es.ts @@ -24,9 +24,40 @@ export interface ElasticsearchSourceKibanaStats { }; } +export interface ElasticsearchSourceLogstashPipelineVertex { + id: string; + plugin_type: string; + stats?: { + [key: string]: { + data?: any[]; + }; + }; +} + export interface ElasticsearchSource { timestamp: string; kibana_stats?: ElasticsearchSourceKibanaStats; + logstash_state?: { + pipeline?: { + representation?: { + graph?: { + vertices?: ElasticsearchSourceLogstashPipelineVertex[]; + }; + }; + }; + }; + logstash_stats?: { + timestamp?: string; + logstash?: {}; + events?: {}; + reloads?: {}; + queue?: { + type?: string; + }; + jvm?: { + uptime_in_millis?: number; + }; + }; beats_stats?: { timestamp?: string; beat?: { diff --git a/x-pack/plugins/monitoring/server/lib/logstash/get_node_info.js b/x-pack/plugins/monitoring/server/lib/logstash/get_node_info.ts similarity index 65% rename from x-pack/plugins/monitoring/server/lib/logstash/get_node_info.js rename to x-pack/plugins/monitoring/server/lib/logstash/get_node_info.ts index fdfc523e53527..ead8764607786 100644 --- a/x-pack/plugins/monitoring/server/lib/logstash/get_node_info.js +++ b/x-pack/plugins/monitoring/server/lib/logstash/get_node_info.ts @@ -4,24 +4,31 @@ * you may not use this file except in compliance with the Elastic License. */ -import { get, merge } from 'lodash'; +import { merge } from 'lodash'; +// @ts-ignore import { checkParam } from '../error_missing_required'; -import { calculateAvailability } from './../calculate_availability'; +// @ts-ignore +import { calculateAvailability } from '../calculate_availability'; +import { LegacyRequest, ElasticsearchResponse } from '../../types'; -export function handleResponse(resp) { - const source = get(resp, 'hits.hits[0]._source.logstash_stats'); - const logstash = get(source, 'logstash'); +export function handleResponse(resp: ElasticsearchResponse) { + const source = resp.hits?.hits[0]?._source?.logstash_stats; + const logstash = source?.logstash; const info = merge(logstash, { - availability: calculateAvailability(get(source, 'timestamp')), - events: get(source, 'events'), - reloads: get(source, 'reloads'), - queue_type: get(source, 'queue.type'), - uptime: get(source, 'jvm.uptime_in_millis'), + availability: calculateAvailability(source?.timestamp), + events: source?.events, + reloads: source?.reloads, + queue_type: source?.queue?.type, + uptime: source?.jvm?.uptime_in_millis, }); return info; } -export function getNodeInfo(req, lsIndexPattern, { clusterUuid, logstashUuid }) { +export function getNodeInfo( + req: LegacyRequest, + lsIndexPattern: string, + { clusterUuid, logstashUuid }: { clusterUuid: string; logstashUuid: string } +) { checkParam(lsIndexPattern, 'lsIndexPattern in getNodeInfo'); const params = { diff --git a/x-pack/plugins/monitoring/server/lib/logstash/get_pipeline.js b/x-pack/plugins/monitoring/server/lib/logstash/get_pipeline.ts similarity index 78% rename from x-pack/plugins/monitoring/server/lib/logstash/get_pipeline.js rename to x-pack/plugins/monitoring/server/lib/logstash/get_pipeline.ts index 2977159f4206d..0461d69e3d68d 100644 --- a/x-pack/plugins/monitoring/server/lib/logstash/get_pipeline.js +++ b/x-pack/plugins/monitoring/server/lib/logstash/get_pipeline.ts @@ -6,16 +6,24 @@ import boom from '@hapi/boom'; import { get } from 'lodash'; +// @ts-ignore import { checkParam } from '../error_missing_required'; import { getPipelineStateDocument } from './get_pipeline_state_document'; +// @ts-ignore import { getPipelineStatsAggregation } from './get_pipeline_stats_aggregation'; +// @ts-ignore import { calculateTimeseriesInterval } from '../calculate_timeseries_interval'; +import { LegacyRequest } from '../../types'; +import { + ElasticsearchSource, + ElasticsearchSourceLogstashPipelineVertex, +} from '../../../common/types/es'; export function _vertexStats( - vertex, - vertexStatsBucket, - totalProcessorsDurationInMillis, - timeseriesIntervalInSeconds + vertex: ElasticsearchSourceLogstashPipelineVertex, + vertexStatsBucket: any, + totalProcessorsDurationInMillis: number, + timeseriesIntervalInSeconds: number ) { const isInput = vertex.plugin_type === 'input'; const isProcessor = vertex.plugin_type === 'filter' || vertex.plugin_type === 'output'; @@ -27,8 +35,11 @@ export function _vertexStats( const durationInMillis = vertexStatsBucket.duration_in_millis_total.value; - const processorStats = {}; - const eventsProcessedStats = { + const processorStats: any = {}; + const eventsProcessedStats: { + events_out_per_millisecond: number; + events_in_per_millisecond?: number; + } = { events_out_per_millisecond: eventsOutTotal / timeseriesIntervalInMillis, }; @@ -63,14 +74,14 @@ export function _vertexStats( * @param {Integer} timeseriesIntervalInSeconds The size of each timeseries bucket, in seconds */ export function _enrichStateWithStatsAggregation( - stateDocument, - statsAggregation, - timeseriesIntervalInSeconds + stateDocument: ElasticsearchSource, + statsAggregation: any, + timeseriesIntervalInSeconds: number ) { const logstashState = stateDocument.logstash_state; - const vertices = logstashState.pipeline.representation.graph.vertices; + const vertices = logstashState?.pipeline?.representation?.graph?.vertices ?? []; - const verticesById = {}; + const verticesById: any = {}; vertices.forEach((vertex) => { verticesById[vertex.id] = vertex; vertex.stats = {}; @@ -82,7 +93,7 @@ export function _enrichStateWithStatsAggregation( const verticesWithStatsBuckets = statsAggregation.aggregations.pipelines.scoped.vertices.vertex_id.buckets; - verticesWithStatsBuckets.forEach((vertexStatsBucket) => { + verticesWithStatsBuckets.forEach((vertexStatsBucket: any) => { // Each vertexStats bucket contains a list of stats for a single vertex within a single timeseries interval const vertexId = vertexStatsBucket.key; const vertex = verticesById[vertexId]; @@ -98,13 +109,20 @@ export function _enrichStateWithStatsAggregation( } }); - return stateDocument.logstash_state.pipeline; + return stateDocument.logstash_state?.pipeline; } -export async function getPipeline(req, config, lsIndexPattern, clusterUuid, pipelineId, version) { +export async function getPipeline( + req: LegacyRequest, + config: { get: (key: string) => string | undefined }, + lsIndexPattern: string, + clusterUuid: string, + pipelineId: string, + version: { firstSeen: string; lastSeen: string; hash: string } +) { checkParam(lsIndexPattern, 'lsIndexPattern in getPipeline'); - const options = { + const options: any = { clusterUuid, pipelineId, version, diff --git a/x-pack/plugins/monitoring/server/lib/logstash/get_pipeline_state_document.js b/x-pack/plugins/monitoring/server/lib/logstash/get_pipeline_state_document.ts similarity index 75% rename from x-pack/plugins/monitoring/server/lib/logstash/get_pipeline_state_document.js rename to x-pack/plugins/monitoring/server/lib/logstash/get_pipeline_state_document.ts index dae8d52e6c57b..96419ceb4cc70 100644 --- a/x-pack/plugins/monitoring/server/lib/logstash/get_pipeline_state_document.js +++ b/x-pack/plugins/monitoring/server/lib/logstash/get_pipeline_state_document.ts @@ -4,16 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ +// @ts-ignore import { createQuery } from '../create_query'; +// @ts-ignore import { LogstashMetric } from '../metrics'; -import { get } from 'lodash'; +import { LegacyRequest, ElasticsearchResponse } from '../../types'; export async function getPipelineStateDocument( - req, - logstashIndexPattern, - { clusterUuid, pipelineId, version } + req: LegacyRequest, + logstashIndexPattern: string, + { + clusterUuid, + pipelineId, + version, + }: { clusterUuid: string; pipelineId: string; version: { hash: string } } ) { - const { callWithRequest } = req.server.plugins.elasticsearch.getCluster('monitoring'); + const { callWithRequest } = req.server.plugins?.elasticsearch.getCluster('monitoring'); const filters = [ { term: { 'logstash_state.pipeline.id': pipelineId } }, { term: { 'logstash_state.pipeline.hash': version.hash } }, @@ -43,8 +49,8 @@ export async function getPipelineStateDocument( }, }; - const resp = await callWithRequest(req, 'search', params); + const resp = (await callWithRequest(req, 'search', params)) as ElasticsearchResponse; // Return null if doc not found - return get(resp, 'hits.hits[0]._source', null); + return resp.hits?.hits[0]?._source ?? null; } diff --git a/x-pack/plugins/monitoring/server/lib/logstash/get_pipeline_vertex.js b/x-pack/plugins/monitoring/server/lib/logstash/get_pipeline_vertex.ts similarity index 73% rename from x-pack/plugins/monitoring/server/lib/logstash/get_pipeline_vertex.js rename to x-pack/plugins/monitoring/server/lib/logstash/get_pipeline_vertex.ts index cdbe26d993f75..b275e4c7bc207 100644 --- a/x-pack/plugins/monitoring/server/lib/logstash/get_pipeline_vertex.js +++ b/x-pack/plugins/monitoring/server/lib/logstash/get_pipeline_vertex.ts @@ -6,16 +6,24 @@ import boom from '@hapi/boom'; import { get } from 'lodash'; +// @ts-ignore import { checkParam } from '../error_missing_required'; import { getPipelineStateDocument } from './get_pipeline_state_document'; +// @ts-ignore import { getPipelineVertexStatsAggregation } from './get_pipeline_vertex_stats_aggregation'; +// @ts-ignore import { calculateTimeseriesInterval } from '../calculate_timeseries_interval'; +import { LegacyRequest } from '../../types'; +import { + ElasticsearchSource, + ElasticsearchSourceLogstashPipelineVertex, +} from '../../../common/types/es'; export function _vertexStats( - vertex, - vertexStatsBucket, - totalProcessorsDurationInMillis, - timeseriesIntervalInSeconds + vertex: ElasticsearchSourceLogstashPipelineVertex, + vertexStatsBucket: any, + totalProcessorsDurationInMillis: number, + timeseriesIntervalInSeconds: number ) { const isInput = vertex.plugin_type === 'input'; const isProcessor = vertex.plugin_type === 'filter' || vertex.plugin_type === 'output'; @@ -27,9 +35,12 @@ export function _vertexStats( const durationInMillis = vertexStatsBucket.duration_in_millis_total.value; - const inputStats = {}; - const processorStats = {}; - const eventsProcessedStats = { + const inputStats: any = {}; + const processorStats: any = {}; + const eventsProcessedStats: { + events_out_per_millisecond: number; + events_in_per_millisecond?: number; + } = { events_out_per_millisecond: eventsOutTotal / timeseriesIntervalInMillis, }; @@ -72,21 +83,23 @@ export function _vertexStats( * @param {Integer} timeseriesIntervalInSeconds The size of each timeseries bucket, in seconds */ export function _enrichVertexStateWithStatsAggregation( - stateDocument, - vertexStatsAggregation, - vertexId, - timeseriesIntervalInSeconds + stateDocument: ElasticsearchSource, + vertexStatsAggregation: any, + vertexId: string, + timeseriesIntervalInSeconds: number ) { const logstashState = stateDocument.logstash_state; - const vertices = logstashState.pipeline.representation.graph.vertices; + const vertices = logstashState?.pipeline?.representation?.graph?.vertices; // First, filter out the vertex we care about - const vertex = vertices.find((v) => v.id === vertexId); - vertex.stats = {}; + const vertex = vertices?.find((v) => v.id === vertexId); + if (vertex) { + vertex.stats = {}; + } // Next, iterate over timeseries metrics and attach them to vertex const timeSeriesBuckets = vertexStatsAggregation.aggregations.timeseries.buckets; - timeSeriesBuckets.forEach((timeSeriesBucket) => { + timeSeriesBuckets.forEach((timeSeriesBucket: any) => { // each bucket calculates stats for total pipeline CPU time for the associated timeseries const totalDurationStats = timeSeriesBucket.pipelines.scoped.total_processor_duration_stats; const totalProcessorsDurationInMillis = totalDurationStats.max - totalDurationStats.min; @@ -94,31 +107,35 @@ export function _enrichVertexStateWithStatsAggregation( const timestamp = timeSeriesBucket.key; const vertexStatsBucket = timeSeriesBucket.pipelines.scoped.vertices.vertex_id; - const vertexStats = _vertexStats( - vertex, - vertexStatsBucket, - totalProcessorsDurationInMillis, - timeseriesIntervalInSeconds - ); - Object.keys(vertexStats).forEach((stat) => { - if (!vertex.stats.hasOwnProperty(stat)) { - vertex.stats[stat] = { data: [] }; - } - vertex.stats[stat].data.push([timestamp, vertexStats[stat]]); - }); + if (vertex) { + const vertexStats = _vertexStats( + vertex, + vertexStatsBucket, + totalProcessorsDurationInMillis, + timeseriesIntervalInSeconds + ); + Object.keys(vertexStats).forEach((stat) => { + if (vertex?.stats) { + if (!vertex.stats.hasOwnProperty(stat)) { + vertex.stats[stat] = { data: [] }; + } + vertex.stats[stat].data?.push([timestamp, vertexStats[stat]]); + } + }); + } }); return vertex; } export async function getPipelineVertex( - req, - config, - lsIndexPattern, - clusterUuid, - pipelineId, - version, - vertexId + req: LegacyRequest, + config: { get: (key: string) => string | undefined }, + lsIndexPattern: string, + clusterUuid: string, + pipelineId: string, + version: { hash: string; firstSeen: string; lastSeen: string }, + vertexId: string ) { checkParam(lsIndexPattern, 'lsIndexPattern in getPipeline'); From a21ad0d126e2378e0b12b6e3d3613cc693e57279 Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Tue, 12 Jan 2021 11:48:18 -0500 Subject: [PATCH 48/64] [Monitoring] Remove deprecated watcher-based cluster alerts (#85047) * First draft * Update to use actual API * Remove this file * Update translation key Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../{security_toasts.tsx => alerts_toast.tsx} | 57 ++++++++++++++----- .../monitoring/public/services/clusters.js | 4 +- .../server/es_client/instantiate_client.ts | 3 +- .../monitoring_endpoint_disable_watches.ts | 20 +++++++ .../alerts/disable_watcher_cluster_alerts.ts | 49 ++++++++++++++++ x-pack/plugins/monitoring/server/plugin.ts | 2 + .../server/routes/api/v1/alerts/enable.ts | 21 +++++-- x-pack/plugins/monitoring/server/types.ts | 4 +- 8 files changed, 137 insertions(+), 23 deletions(-) rename x-pack/plugins/monitoring/public/alerts/lib/{security_toasts.tsx => alerts_toast.tsx} (50%) create mode 100644 x-pack/plugins/monitoring/server/es_client/monitoring_endpoint_disable_watches.ts create mode 100644 x-pack/plugins/monitoring/server/lib/alerts/disable_watcher_cluster_alerts.ts diff --git a/x-pack/plugins/monitoring/public/alerts/lib/security_toasts.tsx b/x-pack/plugins/monitoring/public/alerts/lib/alerts_toast.tsx similarity index 50% rename from x-pack/plugins/monitoring/public/alerts/lib/security_toasts.tsx rename to x-pack/plugins/monitoring/public/alerts/lib/alerts_toast.tsx index 2850a5b772c32..f478545046894 100644 --- a/x-pack/plugins/monitoring/public/alerts/lib/security_toasts.tsx +++ b/x-pack/plugins/monitoring/public/alerts/lib/alerts_toast.tsx @@ -11,9 +11,10 @@ import { EuiSpacer, EuiLink } from '@elastic/eui'; import { Legacy } from '../../legacy_shims'; import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public'; -export interface AlertingFrameworkHealth { - isSufficientlySecure: boolean; - hasPermanentEncryptionKey: boolean; +export interface EnableAlertResponse { + isSufficientlySecure?: boolean; + hasPermanentEncryptionKey?: boolean; + disabledWatcherClusterAlerts?: boolean; } const showTlsAndEncryptionError = () => { @@ -48,18 +49,48 @@ const showTlsAndEncryptionError = () => { }); }; -export const showSecurityToast = (alertingHealth: AlertingFrameworkHealth) => { - const { isSufficientlySecure, hasPermanentEncryptionKey } = alertingHealth; +const showUnableToDisableWatcherClusterAlertsError = () => { + const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = Legacy.shims.docLinks; - if ( - Array.isArray(alertingHealth) || - (!alertingHealth.hasOwnProperty('isSufficientlySecure') && - !alertingHealth.hasOwnProperty('hasPermanentEncryptionKey')) - ) { - return; - } + Legacy.shims.toastNotifications.addWarning({ + title: toMountPoint( + + ), + text: toMountPoint( +
+

+ {i18n.translate('xpack.monitoring.healthCheck.unableToDisableWatches.text', { + defaultMessage: `We failed to remove legacy cluster alerts. Please check the Kibana server log for more details, or try again later.`, + })} +

+ + + {i18n.translate('xpack.monitoring.healthCheck.unableToDisableWatches.action', { + defaultMessage: 'Learn more.', + })} + +
+ ), + }); +}; + +export const showAlertsToast = (response: EnableAlertResponse) => { + const { + isSufficientlySecure, + hasPermanentEncryptionKey, + disabledWatcherClusterAlerts, + } = response; - if (!isSufficientlySecure || !hasPermanentEncryptionKey) { + if (isSufficientlySecure === false || hasPermanentEncryptionKey === false) { showTlsAndEncryptionError(); + } else if (disabledWatcherClusterAlerts === false) { + showUnableToDisableWatcherClusterAlertsError(); } }; diff --git a/x-pack/plugins/monitoring/public/services/clusters.js b/x-pack/plugins/monitoring/public/services/clusters.js index ef97d78b4f745..e94bf990b090c 100644 --- a/x-pack/plugins/monitoring/public/services/clusters.js +++ b/x-pack/plugins/monitoring/public/services/clusters.js @@ -8,7 +8,7 @@ import { ajaxErrorHandlersProvider } from '../lib/ajax_error_handler'; import { Legacy } from '../legacy_shims'; import { STANDALONE_CLUSTER_CLUSTER_UUID } from '../../common/constants'; import { showInternalMonitoringToast } from '../lib/internal_monitoring_toasts'; -import { showSecurityToast } from '../alerts/lib/security_toasts'; +import { showAlertsToast } from '../alerts/lib/alerts_toast'; function formatClusters(clusters) { return clusters.map(formatCluster); @@ -94,7 +94,7 @@ export function monitoringClustersProvider($injector) { if (clusters.length) { try { const [{ data }] = await Promise.all([ensureAlertsEnabled(), ensureMetricbeatEnabled()]); - showSecurityToast(data); + showAlertsToast(data); once = true; } catch (_err) { // Intentionally swallow the error as this will retry the next page load diff --git a/x-pack/plugins/monitoring/server/es_client/instantiate_client.ts b/x-pack/plugins/monitoring/server/es_client/instantiate_client.ts index d974685384634..734caa7374686 100644 --- a/x-pack/plugins/monitoring/server/es_client/instantiate_client.ts +++ b/x-pack/plugins/monitoring/server/es_client/instantiate_client.ts @@ -7,6 +7,7 @@ import { ConfigOptions } from 'elasticsearch'; import { Logger, ILegacyCustomClusterClient } from 'kibana/server'; // @ts-ignore import { monitoringBulk } from '../kibana_monitoring/lib/monitoring_bulk'; +import { monitoringEndpointDisableWatches } from './monitoring_endpoint_disable_watches'; import { MonitoringElasticsearchConfig } from '../config'; /* Provide a dedicated Elasticsearch client for Monitoring @@ -28,7 +29,7 @@ export function instantiateClient( const isMonitoringCluster = hasMonitoringCluster(elasticsearchConfig); const cluster = createClient('monitoring', { ...(isMonitoringCluster ? elasticsearchConfig : {}), - plugins: [monitoringBulk], + plugins: [monitoringBulk, monitoringEndpointDisableWatches], logQueries: Boolean(elasticsearchConfig.logQueries), } as ESClusterConfig); diff --git a/x-pack/plugins/monitoring/server/es_client/monitoring_endpoint_disable_watches.ts b/x-pack/plugins/monitoring/server/es_client/monitoring_endpoint_disable_watches.ts new file mode 100644 index 0000000000000..ef4358d3eff8b --- /dev/null +++ b/x-pack/plugins/monitoring/server/es_client/monitoring_endpoint_disable_watches.ts @@ -0,0 +1,20 @@ +/* + * 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 function monitoringEndpointDisableWatches(Client: any, _config: any, components: any) { + const ca = components.clientAction.factory; + Client.prototype.monitoring = components.clientAction.namespaceFactory(); + const monitoring = Client.prototype.monitoring.prototype; + monitoring.disableWatches = ca({ + params: {}, + urls: [ + { + fmt: '_monitoring/migrate/alerts', + }, + ], + method: 'POST', + }); +} diff --git a/x-pack/plugins/monitoring/server/lib/alerts/disable_watcher_cluster_alerts.ts b/x-pack/plugins/monitoring/server/lib/alerts/disable_watcher_cluster_alerts.ts new file mode 100644 index 0000000000000..5dc0b6d0faaa4 --- /dev/null +++ b/x-pack/plugins/monitoring/server/lib/alerts/disable_watcher_cluster_alerts.ts @@ -0,0 +1,49 @@ +/* + * 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 'kibana/server'; +import { LegacyAPICaller } from 'src/core/server'; + +interface DisableWatchesResponse { + exporters: Array< + Array<{ + name: string; + type: string; + migration_complete: boolean; + reason?: { + type: string; + reason: string; + }; + }> + >; +} + +async function callMigrationApi(callCluster: LegacyAPICaller) { + return await callCluster('monitoring.disableWatches'); +} + +export async function disableWatcherClusterAlerts(callCluster: LegacyAPICaller, logger: Logger) { + const response: DisableWatchesResponse = await callMigrationApi(callCluster); + if (!response || response.exporters.length === 0) { + return true; + } + const list = response.exporters[0]; + if (list.length === 0) { + return true; + } + + let removedAll = true; + for (const exporter of list) { + if (!exporter.migration_complete) { + if (exporter.reason) { + logger.warn( + `Unable to remove exporter type=${exporter.type} and name=${exporter.name} because ${exporter.reason.type}: ${exporter.reason.reason}` + ); + removedAll = false; + } + } + } + return removedAll; +} diff --git a/x-pack/plugins/monitoring/server/plugin.ts b/x-pack/plugins/monitoring/server/plugin.ts index 9af95019dafd8..c7b3f13dd6954 100644 --- a/x-pack/plugins/monitoring/server/plugin.ts +++ b/x-pack/plugins/monitoring/server/plugin.ts @@ -211,9 +211,11 @@ export class Plugin { this.registerPluginInUI(plugins); requireUIRoutes(this.monitoringCore, { + cluster, router, licenseService: this.licenseService, encryptedSavedObjects: plugins.encryptedSavedObjects, + logger: this.log, }); initInfraSource(config, plugins.infra); } diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts index ac38d7a59b773..9d11733ec0386 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts @@ -11,6 +11,8 @@ import { RouteDependencies } from '../../../../types'; import { ALERT_ACTION_TYPE_LOG } from '../../../../../common/constants'; import { ActionResult } from '../../../../../../actions/common'; import { AlertingSecurity } from '../../../../lib/elasticsearch/verify_alerting_security'; +import { disableWatcherClusterAlerts } from '../../../../lib/alerts/disable_watcher_cluster_alerts'; +import { Alert, AlertTypeParams } from '../../../../../../alerts/common'; const DEFAULT_SERVER_LOG_NAME = 'Monitoring: Write to Kibana log'; @@ -20,7 +22,7 @@ export function enableAlertsRoute(_server: unknown, npRoute: RouteDependencies) path: '/api/monitoring/v1/alerts/enable', validate: false, }, - async (context, _request, response) => { + async (context, request, response) => { try { const alerts = AlertsFactory.getAll().filter((a) => a.isEnabled(npRoute.licenseService)); @@ -75,12 +77,19 @@ export function enableAlertsRoute(_server: unknown, npRoute: RouteDependencies) }, ]; - const createdAlerts = await Promise.all( - alerts.map( - async (alert) => await alert.createIfDoesNotExist(alertsClient, actionsClient, actions) - ) + let createdAlerts: Array> = []; + const disabledWatcherClusterAlerts = await disableWatcherClusterAlerts( + npRoute.cluster.asScoped(request).callAsCurrentUser, + npRoute.logger ); - return response.ok({ body: createdAlerts }); + + if (disabledWatcherClusterAlerts) { + createdAlerts = await Promise.all( + alerts.map((alert) => alert.createIfDoesNotExist(alertsClient, actionsClient, actions)) + ); + } + + return response.ok({ body: { createdAlerts, disabledWatcherClusterAlerts } }); } catch (err) { throw handleError(err); } diff --git a/x-pack/plugins/monitoring/server/types.ts b/x-pack/plugins/monitoring/server/types.ts index 4fbc1c494f14c..47ac3beb8c390 100644 --- a/x-pack/plugins/monitoring/server/types.ts +++ b/x-pack/plugins/monitoring/server/types.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { Observable } from 'rxjs'; -import { IRouter, ILegacyClusterClient, Logger } from 'kibana/server'; +import { IRouter, ILegacyClusterClient, Logger, ILegacyCustomClusterClient } from 'kibana/server'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { LicenseFeature, ILicense } from '../../licensing/server'; import { PluginStartContract as ActionsPluginsStartContact } from '../../actions/server'; @@ -53,9 +53,11 @@ export interface MonitoringCoreConfig { } export interface RouteDependencies { + cluster: ILegacyCustomClusterClient; router: IRouter; licenseService: MonitoringLicenseService; encryptedSavedObjects?: EncryptedSavedObjectsPluginSetup; + logger: Logger; } export interface MonitoringCore { From 4afaa2d6ff740317faaa6dd8cbdc6de2321023c4 Mon Sep 17 00:00:00 2001 From: EamonnTP Date: Tue, 12 Jan 2021 16:53:30 +0000 Subject: [PATCH 49/64] docs: Add content for the new Service Overview page (#87496) * Add service overview content * Edits following reviews * Review edits --- docs/apm/images/all-instances.png | Bin 0 -> 198846 bytes docs/apm/images/error-rate.png | Bin 0 -> 396055 bytes docs/apm/images/latency.png | Bin 0 -> 106853 bytes docs/apm/images/metadata-icons.png | Bin 0 -> 14332 bytes docs/apm/images/spans-dependencies.png | Bin 0 -> 421566 bytes docs/apm/images/traffic-transactions.png | Bin 0 -> 395228 bytes docs/apm/service-overview.asciidoc | 105 ++++++++++++++++++++++- docs/apm/transactions.asciidoc | 1 + 8 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 docs/apm/images/all-instances.png create mode 100644 docs/apm/images/error-rate.png create mode 100644 docs/apm/images/latency.png create mode 100644 docs/apm/images/metadata-icons.png create mode 100644 docs/apm/images/spans-dependencies.png create mode 100644 docs/apm/images/traffic-transactions.png diff --git a/docs/apm/images/all-instances.png b/docs/apm/images/all-instances.png new file mode 100644 index 0000000000000000000000000000000000000000..e77c8af2c46f6a978f7ba00509ff7b5e86bc0b86 GIT binary patch literal 198846 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

RerD2e(pmmkKK}_}QA+Ts@6{VD4hbw3Qp0)kh6! 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

D;SXC9O%v$P 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

=bkxG)lTLD@EJ0g>$M5*wkt65N%a*`I3lAyL0 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

x$#&@^7CjtvXPjJneC>`gc| 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

TpF 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

  • ~(veSRFP{(LyF?a_r4hoBJYl@cxB!z| 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 literal 0 HcmV?d00001 diff --git a/docs/apm/images/latency.png b/docs/apm/images/latency.png new file mode 100644 index 0000000000000000000000000000000000000000..4c970d8c582e6ac0ce0b29e41eb2193541140db7 GIT binary patch literal 106853 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

    a2D4HKD!+;l3VQ24p_-w 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

    -KigUOp~%#4vCxQgJNvXek-(N6@Kj~) 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ℑqN1-?b}1(ATCB5K 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%0A0n`I!;$z(DpVBkFut3_t6jQYx(YT=zC-IuC*s}z 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%0D3dmlv0SdXQZXu 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

    NBt#n( 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%0Db&gnk$`T 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 brings you to the *Service overview*. \ No newline at end of file +Selecting a <> brings you to the *Service overview*. +The *Service overview* contains a wide variety of charts and tables that provide +visibility into how a service performs across your infrastructure. + +[discrete] +[[service-latency]] +=== Latency + +Response times for the service. You can filter the *Latency* chart to display the average, +95th, or 99th percentile latency times for the service. + +[role="screenshot"] +image::apm/images/latency.png[Service latency] + +[discrete] +[[service-traffic-transactions]] +=== Traffic and transactions + +The *Traffic* chart visualizes the average number of transactions per minute for the selected service. + +The *Transactions* table displays a list of _transaction groups_ for the +selected service and includes the latency, traffic, error rate, and the impact for each transaction. +Transactions that share the same name are grouped, and only one entry is displayed for each group. + +By default, transaction groups are sorted by _Impact_ to show the most used and slowest endpoints in your +service. If there is a particular endpoint you are interested in, click *View transactions* to view a +list of similar transactions on the <> page. + +[role="screenshot"] +image::apm/images/traffic-transactions.png[Traffic and transactions] + +[discrete] +[[service-error-rates]] +=== Error rate and errors + +The *Error rate* chart displays the average error rates relating to the service, within a specific time range. + +The *Errors* table provides a high-level view of each error message when it first and last occurred, +along with the total number of occurrences. This makes it very easy to quickly see which errors affect +your services and take actions to rectify them. To do so, click *View errors*. + +[role="screenshot"] +image::apm/images/error-rate.png[Error rate and errors] + +[discrete] +[[service-span-duration]] +=== Span types average duration and dependencies + +The *Average duration by span type* chart visualizes each span type's average duration and helps you determine +which spans could be slowing down transactions. The "app" label displayed under the +chart indicates that something was happening within the application. This could signal that the +agent does not have auto-instrumentation for whatever was happening during that time or that the time was spent in the +application code and not in database or external requests. + +The *Dependencies* table displays a list of downstream services or external connections relevant +to the service at the selected time range. The table displays latency, traffic, error rate, and the impact of +each dependency. By default, dependencies are sorted by _Impact_ to show the most used and the slowest dependency. +If there is a particular dependency you are interested in, click *View service map* to view the related +<>. + +[role="screenshot"] +image::apm/images/spans-dependencies.png[Span type duration and dependencies] + +[discrete] +[[service-instances]] +=== All instances + +The *All instances* table displays a list of all the available service instances within the selected time range. +Depending on how the service runs, the instance could be a host or a container. The table displays latency, traffic, +errors, CPU usage, and memory usage for each instance. By default, instances are sorted by _Traffic_. + +[role="screenshot"] +image::apm/images/all-instances.png[All instances] + +[discrete] +[[service-metadata]] +=== Service metadata + +To view metadata relating to the service agent, and if relevant, the container and cloud provider, +click on each icon located at the top of the page beside the service name. + +[role="screenshot"] +image::apm/images/metadata-icons.png[Service metadata] + +*Service information* + +* Service version +* Runtime name and version +* Framework name +* Agent name and version + +*Container information* + +* Operating system +* Containerized - Yes or no. +* Total number of instances +* Orchestration + +*Cloud provider information* + +* Cloud provider +* Availability zones +* Machine types +* Project ID diff --git a/docs/apm/transactions.asciidoc b/docs/apm/transactions.asciidoc index 3f624980e3937..83ca9e5a10a9b 100644 --- a/docs/apm/transactions.asciidoc +++ b/docs/apm/transactions.asciidoc @@ -24,6 +24,7 @@ Like in the Transaction duration graph, you can zoom in on anomalies to further *Error rate*:: Visualize the total number of transactions with errors divided by the total number of transactions. +The error rate value is based on the `event.outcome` field and is the relative number of failed transactions. Any unexpected increases, decreases, or irregular patterns can be investigated further with the <>. From 8fe204fcab5926ecd28b1ebfad1e62dd035ba822 Mon Sep 17 00:00:00 2001 From: Patrick Mueller Date: Tue, 12 Jan 2021 11:54:40 -0500 Subject: [PATCH 50/64] [actions] fixes action proxies to set the right agent based on target url (#86415) Previously, the http and https proxy agents used by actions were created based on the protocol of the proxy URL itself - if the proxy was an http URL, both the generated http and https agents supplied to axios were actually both http proxy agents; if the proxy was an https URL, both the generated http and https agents supplied to axios were both https proxy agents. This PR changes so that both an http and https proxy agent are created and assigned as the appropriate agents for axios. Similar changes were made to the slack action, which does not directly use axios. --- .../lib/axios_utils.test.ts | 50 ++++++-- .../builtin_action_types/lib/axios_utils.ts | 12 +- .../lib/get_proxy_agent.test.ts | 30 ----- .../lib/get_proxy_agent.ts | 31 ----- .../lib/get_proxy_agents.test.ts | 44 +++++++ .../lib/get_proxy_agents.ts | 52 ++++++++ .../server/builtin_action_types/slack.ts | 16 +-- .../server/manual_tests/forward_proxy.js | 112 ++++++++++++++++++ 8 files changed, 267 insertions(+), 80 deletions(-) delete mode 100644 x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agent.test.ts delete mode 100644 x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agent.ts create mode 100644 x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agents.test.ts create mode 100644 x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agents.ts create mode 100644 x-pack/plugins/actions/server/manual_tests/forward_proxy.js diff --git a/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.test.ts b/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.test.ts index 7e938e766657c..32e1b233274c9 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.test.ts @@ -5,10 +5,11 @@ */ import axios from 'axios'; -import HttpProxyAgent from 'http-proxy-agent'; import { Logger } from '../../../../../../src/core/server'; import { addTimeZoneToDate, request, patch, getErrorMessage } from './axios_utils'; import { loggingSystemMock } from '../../../../../../src/core/server/mocks'; +import { getProxyAgents } from './get_proxy_agents'; + const logger = loggingSystemMock.create().get() as jest.Mocked; jest.mock('axios'); const axiosMock = (axios as unknown) as jest.Mock; @@ -27,6 +28,7 @@ describe('addTimeZoneToDate', () => { describe('request', () => { beforeEach(() => { + jest.resetAllMocks(); axiosMock.mockImplementation(() => ({ status: 200, headers: { 'content-type': 'application/json' }, @@ -58,23 +60,57 @@ describe('request', () => { }); }); - test('it have been called with proper proxy agent', async () => { + test('it have been called with proper proxy agent for a valid url', async () => { + const proxySettings = { + proxyRejectUnauthorizedCertificates: true, + proxyUrl: 'https://localhost:1212', + }; + const { httpAgent, httpsAgent } = getProxyAgents(proxySettings, logger); + const res = await request({ axios, - url: '/testProxy', + url: 'http://testProxy', logger, proxySettings: { - proxyUrl: 'http://localhost:1212', + proxyUrl: 'https://localhost:1212', + proxyRejectUnauthorizedCertificates: true, + }, + }); + + expect(axiosMock).toHaveBeenCalledWith('http://testProxy', { + method: 'get', + data: {}, + headers: undefined, + httpAgent, + httpsAgent, + params: undefined, + proxy: false, + validateStatus: undefined, + }); + expect(res).toEqual({ + status: 200, + headers: { 'content-type': 'application/json' }, + data: { incidentId: '123' }, + }); + }); + + test('it have been called with proper proxy agent for an invalid url', async () => { + const res = await request({ + axios, + url: 'https://testProxy', + logger, + proxySettings: { + proxyUrl: ':nope:', proxyRejectUnauthorizedCertificates: false, }, }); - expect(axiosMock).toHaveBeenCalledWith('/testProxy', { + expect(axiosMock).toHaveBeenCalledWith('https://testProxy', { method: 'get', data: {}, headers: undefined, - httpAgent: new HttpProxyAgent('http://localhost:1212'), - httpsAgent: new HttpProxyAgent('http://localhost:1212'), + httpAgent: undefined, + httpsAgent: undefined, params: undefined, proxy: false, validateStatus: undefined, diff --git a/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts b/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts index e26a3b686179c..322da1077af18 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts @@ -7,7 +7,7 @@ import { AxiosInstance, Method, AxiosResponse, AxiosBasicCredentials } from 'axios'; import { Logger } from '../../../../../../src/core/server'; import { ProxySettings } from '../../types'; -import { getProxyAgent } from './get_proxy_agent'; +import { getProxyAgents } from './get_proxy_agents'; export const request = async ({ axios, @@ -32,15 +32,17 @@ export const request = async ({ validateStatus?: (status: number) => boolean; auth?: AxiosBasicCredentials; }): Promise => { + const { httpAgent, httpsAgent } = getProxyAgents(proxySettings, logger); + return await axios(url, { method, data: data ?? {}, params, auth, - // use httpsAgent and embedded proxy: false, to be able to handle fail on invalid certs - httpsAgent: proxySettings ? getProxyAgent(proxySettings, logger) : undefined, - httpAgent: proxySettings ? getProxyAgent(proxySettings, logger) : undefined, - proxy: false, // the same way as it done for IncomingWebhook in + // use httpAgent and httpsAgent and set axios proxy: false, to be able to handle fail on invalid certs + httpAgent, + httpsAgent, + proxy: false, headers, validateStatus, }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agent.test.ts b/x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agent.test.ts deleted file mode 100644 index 8623a67e8a68e..0000000000000 --- a/x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agent.test.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import HttpProxyAgent from 'http-proxy-agent'; -import { HttpsProxyAgent } from 'https-proxy-agent'; -import { Logger } from '../../../../../../src/core/server'; -import { getProxyAgent } from './get_proxy_agent'; -import { loggingSystemMock } from '../../../../../../src/core/server/mocks'; -const logger = loggingSystemMock.create().get() as jest.Mocked; - -describe('getProxyAgent', () => { - test('return HttpsProxyAgent for https proxy url', () => { - const agent = getProxyAgent( - { proxyUrl: 'https://someproxyhost', proxyRejectUnauthorizedCertificates: false }, - logger - ); - expect(agent instanceof HttpsProxyAgent).toBeTruthy(); - }); - - test('return HttpProxyAgent for http proxy url', () => { - const agent = getProxyAgent( - { proxyUrl: 'http://someproxyhost', proxyRejectUnauthorizedCertificates: false }, - logger - ); - expect(agent instanceof HttpProxyAgent).toBeTruthy(); - }); -}); diff --git a/x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agent.ts b/x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agent.ts deleted file mode 100644 index 957d31546b019..0000000000000 --- a/x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agent.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import HttpProxyAgent from 'http-proxy-agent'; -import { HttpsProxyAgent } from 'https-proxy-agent'; -import { Logger } from '../../../../../../src/core/server'; -import { ProxySettings } from '../../types'; - -export function getProxyAgent( - proxySettings: ProxySettings, - logger: Logger -): HttpsProxyAgent | HttpProxyAgent { - logger.debug(`Create proxy agent for ${proxySettings.proxyUrl}.`); - - if (/^https/i.test(proxySettings.proxyUrl)) { - const proxyUrl = new URL(proxySettings.proxyUrl); - return new HttpsProxyAgent({ - host: proxyUrl.hostname, - port: Number(proxyUrl.port), - protocol: proxyUrl.protocol, - headers: proxySettings.proxyHeaders, - // do not fail on invalid certs if value is false - rejectUnauthorized: proxySettings.proxyRejectUnauthorizedCertificates, - }); - } else { - return new HttpProxyAgent(proxySettings.proxyUrl); - } -} diff --git a/x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agents.test.ts b/x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agents.test.ts new file mode 100644 index 0000000000000..759ca92968263 --- /dev/null +++ b/x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agents.test.ts @@ -0,0 +1,44 @@ +/* + * 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 HttpProxyAgent from 'http-proxy-agent'; +import { HttpsProxyAgent } from 'https-proxy-agent'; +import { Logger } from '../../../../../../src/core/server'; +import { getProxyAgents } from './get_proxy_agents'; +import { loggingSystemMock } from '../../../../../../src/core/server/mocks'; +const logger = loggingSystemMock.create().get() as jest.Mocked; + +describe('getProxyAgents', () => { + test('get agents for valid proxy URL', () => { + const { httpAgent, httpsAgent } = getProxyAgents( + { proxyUrl: 'https://someproxyhost', proxyRejectUnauthorizedCertificates: false }, + logger + ); + expect(httpAgent instanceof HttpProxyAgent).toBeTruthy(); + expect(httpsAgent instanceof HttpsProxyAgent).toBeTruthy(); + }); + + test('return undefined agents for invalid proxy URL', () => { + const { httpAgent, httpsAgent } = getProxyAgents( + { proxyUrl: ':nope: not a valid URL', proxyRejectUnauthorizedCertificates: false }, + logger + ); + expect(httpAgent).toBe(undefined); + expect(httpsAgent).toBe(undefined); + }); + + test('return undefined agents for null proxy options', () => { + const { httpAgent, httpsAgent } = getProxyAgents(null, logger); + expect(httpAgent).toBe(undefined); + expect(httpsAgent).toBe(undefined); + }); + + test('return undefined agents for undefined proxy options', () => { + const { httpAgent, httpsAgent } = getProxyAgents(undefined, logger); + expect(httpAgent).toBe(undefined); + expect(httpsAgent).toBe(undefined); + }); +}); diff --git a/x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agents.ts b/x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agents.ts new file mode 100644 index 0000000000000..45f962429ad2b --- /dev/null +++ b/x-pack/plugins/actions/server/builtin_action_types/lib/get_proxy_agents.ts @@ -0,0 +1,52 @@ +/* + * 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 { Agent } from 'http'; +import HttpProxyAgent from 'http-proxy-agent'; +import { HttpsProxyAgent } from 'https-proxy-agent'; +import { Logger } from '../../../../../../src/core/server'; +import { ProxySettings } from '../../types'; + +interface GetProxyAgentsResponse { + httpAgent: Agent | undefined; + httpsAgent: Agent | undefined; +} + +export function getProxyAgents( + proxySettings: ProxySettings | undefined | null, + logger: Logger +): GetProxyAgentsResponse { + const undefinedResponse = { + httpAgent: undefined, + httpsAgent: undefined, + }; + + if (!proxySettings) { + return undefinedResponse; + } + + logger.debug(`Creating proxy agents for proxy: ${proxySettings.proxyUrl}`); + let proxyUrl: URL; + try { + proxyUrl = new URL(proxySettings.proxyUrl); + } catch (err) { + logger.warn(`invalid proxy URL "${proxySettings.proxyUrl}" ignored`); + return undefinedResponse; + } + + const httpAgent = new HttpProxyAgent(proxySettings.proxyUrl); + const httpsAgent = (new HttpsProxyAgent({ + host: proxyUrl.hostname, + port: Number(proxyUrl.port), + protocol: proxyUrl.protocol, + headers: proxySettings.proxyHeaders, + // do not fail on invalid certs if value is false + rejectUnauthorized: proxySettings.proxyRejectUnauthorizedCertificates, + }) as unknown) as Agent; + // vsCode wasn't convinced HttpsProxyAgent is an http.Agent, so we convinced it + + return { httpAgent, httpsAgent }; +} diff --git a/x-pack/plugins/actions/server/builtin_action_types/slack.ts b/x-pack/plugins/actions/server/builtin_action_types/slack.ts index c9a3c39afd049..07ea7b62f3606 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/slack.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/slack.ts @@ -6,8 +6,7 @@ import { URL } from 'url'; import { curry } from 'lodash'; -import { HttpsProxyAgent } from 'https-proxy-agent'; -import HttpProxyAgent from 'http-proxy-agent'; +import { Agent } from 'http'; import { i18n } from '@kbn/i18n'; import { schema, TypeOf } from '@kbn/config-schema'; import { IncomingWebhook, IncomingWebhookResult } from '@slack/webhook'; @@ -24,7 +23,7 @@ import { ExecutorType, } from '../types'; import { ActionsConfigurationUtilities } from '../actions_config'; -import { getProxyAgent } from './lib/get_proxy_agent'; +import { getProxyAgents } from './lib/get_proxy_agents'; export type SlackActionType = ActionType<{}, ActionTypeSecretsType, ActionParamsType, unknown>; export type SlackActionTypeExecutorOptions = ActionTypeExecutorOptions< @@ -128,9 +127,13 @@ async function slackExecutor( const { webhookUrl } = secrets; const { message } = params; - let proxyAgent: HttpsProxyAgent | HttpProxyAgent | undefined; + let httpProxyAgent: Agent | undefined; if (execOptions.proxySettings) { - proxyAgent = getProxyAgent(execOptions.proxySettings, logger); + const httpProxyAgents = getProxyAgents(execOptions.proxySettings, logger); + httpProxyAgent = webhookUrl.toLowerCase().startsWith('https') + ? httpProxyAgents.httpsAgent + : httpProxyAgents.httpAgent; + logger.debug(`IncomingWebhook was called with proxyUrl ${execOptions.proxySettings.proxyUrl}`); } @@ -138,8 +141,7 @@ async function slackExecutor( // https://slack.dev/node-slack-sdk/webhook // node-slack-sdk use Axios inside :) const webhook = new IncomingWebhook(webhookUrl, { - // @ts-expect-error The types exposed by 'HttpsProxyAgent' isn't up to date with 'Agent' - agent: proxyAgent, + agent: httpProxyAgent, }); result = await webhook.send(message); } catch (err) { diff --git a/x-pack/plugins/actions/server/manual_tests/forward_proxy.js b/x-pack/plugins/actions/server/manual_tests/forward_proxy.js new file mode 100644 index 0000000000000..5c48b9d2393ab --- /dev/null +++ b/x-pack/plugins/actions/server/manual_tests/forward_proxy.js @@ -0,0 +1,112 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/* +This module implements two forward http proxies, http on 8080 and https on 8443, +which can be used with the config xpack.actions.proxyUrl to emulate customers +using forward proxies with Kibana actions. You can use either the http or https +versions, both can forward proxy http and https traffic: + + xpack.actions.proxyUrl: http://localhost:8080 + OR + xpack.actions.proxyUrl: https://localhost:8443 + +When using the https-based version, you may need to set the following option +as well: + + xpack.actions.rejectUnauthorized: false + +If the server you are connecting to via the proxy is https and has self-signed +certificates, you'll also need to set + + xpack.actions.proxyRejectUnauthorizedCertificates: false +*/ + +const HTTP_PORT = 8080; +const HTTPS_PORT = 8443; + +// starts http and https proxies to use to test actions within Kibana + +const fs = require('fs'); +const net = require('net'); +const url = require('url'); +const http = require('http'); +const https = require('https'); +const httpProxy = require('http-proxy'); + +const httpsOptions = { + key: fs.readFileSync('packages/kbn-dev-utils/certs/kibana.key', 'utf8'), + cert: fs.readFileSync('packages/kbn-dev-utils/certs/kibana.crt', 'utf8'), +}; + +const proxy = httpProxy.createServer(); + +createServer('http', HTTP_PORT); +createServer('https', HTTPS_PORT); + +function createServer(protocol, port) { + let httpServer; + + if (protocol === 'http') { + httpServer = http.createServer(); + } else { + httpServer = https.createServer(httpsOptions); + } + + httpServer.on('request', httpRequest); + httpServer.on('connect', httpsRequest); + httpServer.listen(port); + log(`proxy server started: ${protocol}:/localhost:${port}`); + + // handle http requests + function httpRequest(req, res) { + log(`${protocol} server: request for: ${req.url}`); + const parsedUrl = url.parse(req.url); + if (parsedUrl.hostname == null) { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('this is a proxy server'); + return; + } + const target = parsedUrl.protocol + '//' + parsedUrl.hostname; + proxy.web(req, res, { target: target, secure: false }); + } + + // handle https requests + // see: https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_event_connect + function httpsRequest(req, socket, head) { + log(`${protocol} proxy server: request for target: https://${req.url}`); + const serverUrl = url.parse('https://' + req.url); + const serverSocket = net.connect(serverUrl.port, serverUrl.hostname, () => { + socket.write('HTTP/1.1 200 Connection Established\r\nProxy-agent: Node-Proxy\r\n\r\n'); + serverSocket.write(head); + serverSocket.pipe(socket); + socket.pipe(serverSocket); + }); + socket.on('error', (err) => { + log(`error on socket to proxy: ${err}`); + socket.destroy(); + serverSocket.destroy(); + }); + serverSocket.on('error', (err) => { + log(`error on socket to target: ${err}`); + socket.destroy(); + serverSocket.destroy(); + }); + } +} + +function log(message) { + console.log(`${new Date().toISOString()} - ${message}`); +} + +/* +Test with: + +curl -v -k --proxy-insecure -x http://127.0.0.1:8080 http://www.google.com +curl -v -k --proxy-insecure -x http://127.0.0.1:8080 https://www.google.com +curl -v -k --proxy-insecure -x https://127.0.0.1:8443 http://www.google.com +curl -v -k --proxy-insecure -x https://127.0.0.1:8443 https://www.google.com +*/ From 2d7a3cedef1d5db072b7777f7562ae9bcc76fd99 Mon Sep 17 00:00:00 2001 From: Devon Thomson Date: Tue, 12 Jan 2021 12:02:35 -0500 Subject: [PATCH 51/64] fixed the duplicated duplicate title warning on Visualize Embeddable Add to Library (#87938) --- .../public/embeddable/visualize_embeddable_factory.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx index 80bf145e2a9f5..94519dceb3014 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx @@ -197,6 +197,7 @@ export class VisualizeEmbeddableFactory const saveOptions = { confirmOverwrite: false, returnToOrigin: true, + isTitleDuplicateConfirmed: true, }; savedVis.title = title; savedVis.copyOnSave = false; From 44ccf285e5210630d42f77f584bf03d9c54ab13e Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Tue, 12 Jan 2021 09:15:07 -0800 Subject: [PATCH 52/64] Move creation of state container to render-time in order to initialize state from URL correctly (#87955) --- .../components/agent_logs/constants.tsx | 1 + .../components/agent_logs/index.tsx | 56 ++++++++++--------- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/constants.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/constants.tsx index 4ee1618a38584..4e802fee3043f 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/constants.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/constants.tsx @@ -36,6 +36,7 @@ export const DEFAULT_LOGS_STATE: AgentLogsState = { query: '', }; +export const STATE_STORAGE_KEY = '_q'; export const STATE_DATASET_FIELD = 'datasets'; export const AGENT_LOG_LEVELS = { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/index.tsx index 0d888a88ec2cb..707bc05904aa5 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/index.tsx @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import React, { memo, useEffect, useState } from 'react'; +import React, { memo, useEffect, useState, useMemo } from 'react'; import { createStateContainer, syncState, @@ -12,38 +12,44 @@ import { PureTransition, getStateFromKbnUrl, } from '../../../../../../../../../../../src/plugins/kibana_utils/public'; -import { DEFAULT_LOGS_STATE } from './constants'; +import { DEFAULT_LOGS_STATE, STATE_STORAGE_KEY } from './constants'; import { AgentLogsUI, AgentLogsProps, AgentLogsState, AgentLogsUrlStateHelper } from './agent_logs'; -const stateStorageKey = '_q'; - -const stateContainer = createStateContainer< - AgentLogsState, - { - update: PureTransition]>; - } ->( - { - ...DEFAULT_LOGS_STATE, - ...getStateFromKbnUrl(stateStorageKey, window.location.href), - }, - { - update: (state) => (updatedState) => ({ ...state, ...updatedState }), - } -); - -const AgentLogsConnected = AgentLogsUrlStateHelper.connect((state) => ({ - state: state || DEFAULT_LOGS_STATE, -}))(AgentLogsUI); - export const AgentLogs: React.FunctionComponent> = memo( ({ agent }) => { + const stateContainer = useMemo( + () => + createStateContainer< + AgentLogsState, + { + update: PureTransition]>; + } + >( + { + ...DEFAULT_LOGS_STATE, + ...getStateFromKbnUrl(STATE_STORAGE_KEY, window.location.href), + }, + { + update: (state) => (updatedState) => ({ ...state, ...updatedState }), + } + ), + [] + ); + + const AgentLogsConnected = useMemo( + () => + AgentLogsUrlStateHelper.connect((state) => ({ + state: state || DEFAULT_LOGS_STATE, + }))(AgentLogsUI), + [] + ); + const [isSyncReady, setIsSyncReady] = useState(false); useEffect(() => { const stateStorage = createKbnUrlStateStorage(); const { start, stop } = syncState({ - storageKey: stateStorageKey, + storageKey: STATE_STORAGE_KEY, stateContainer: stateContainer as INullableBaseStateContainer, stateStorage, }); @@ -54,7 +60,7 @@ export const AgentLogs: React.FunctionComponent> = stop(); stateContainer.set(DEFAULT_LOGS_STATE); }; - }, []); + }, [stateContainer]); return ( From 47cac6c4013575a8daadd37d14ebc9f91ae1f699 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Tue, 12 Jan 2021 17:21:16 +0000 Subject: [PATCH 53/64] chore(NA): move missing canvas plugin tests out of __tests__ folder (#87898) --- .../footer/{__tests__ => }/footer.test.tsx | 8 ++++---- .../footer/{__tests__ => }/page_controls.test.tsx | 8 ++++---- .../footer/{__tests__ => }/page_preview.test.tsx | 8 ++++---- .../footer/{__tests__ => }/scrubber.test.tsx | 8 ++++---- .../__snapshots__/settings.test.tsx.snap | 0 .../{__tests__ => }/autoplay_settings.test.tsx | 8 ++++---- .../settings/{__tests__ => }/settings.test.tsx | 12 ++++++------ .../{__tests__ => }/toolbar_settings.test.tsx | 8 ++++---- .../components/footer/{__tests__ => }/title.test.tsx | 6 +++--- 9 files changed, 33 insertions(+), 33 deletions(-) rename x-pack/plugins/canvas/shareable_runtime/components/footer/{__tests__ => }/footer.test.tsx (82%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/{__tests__ => }/page_controls.test.tsx (89%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/{__tests__ => }/page_preview.test.tsx (75%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/{__tests__ => }/scrubber.test.tsx (81%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/settings/{__tests__ => }/__snapshots__/settings.test.tsx.snap (100%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/settings/{__tests__ => }/autoplay_settings.test.tsx (88%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/settings/{__tests__ => }/settings.test.tsx (89%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/settings/{__tests__ => }/toolbar_settings.test.tsx (78%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/{__tests__ => }/title.test.tsx (82%) diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/__tests__/footer.test.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/footer.test.tsx similarity index 82% rename from x-pack/plugins/canvas/shareable_runtime/components/footer/__tests__/footer.test.tsx rename to x-pack/plugins/canvas/shareable_runtime/components/footer/footer.test.tsx index 9df94127ea51d..254c00f15b375 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/footer/__tests__/footer.test.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/components/footer/footer.test.tsx @@ -6,11 +6,11 @@ import { mount } from 'enzyme'; import React from 'react'; -import { JestContext } from '../../../test/context_jest'; -import { getScrubber as scrubber, getPageControlsCenter as center } from '../../../test/selectors'; -import { Footer } from '../footer'; +import { JestContext } from '../../test/context_jest'; +import { getScrubber as scrubber, getPageControlsCenter as center } from '../../test/selectors'; +import { Footer } from './footer'; -jest.mock('../../../supported_renderers'); +jest.mock('../../supported_renderers'); describe('

    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