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:
You get an error toaster showing up who's content is "Bad Request":
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