From 717e40c4447977aeac1f4e316b400ee22d1a56d5 Mon Sep 17 00:00:00 2001
From: Maja Grubic
Date: Tue, 10 Dec 2019 15:05:05 +0000
Subject: [PATCH 01/24] Move DashboardEmptyScreen inside DashboardViewport
(#51939)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Prototyping adding Visualization to Dashboard
* i18n fixes
* Remvoing dashboard empty screen directive
* Updating test for empty dashboard screen
* Removing unused state variable
* Adding a test for DashboardViewPort
* i18n & minor fixes
* Fixing fullscreen mode view
* Fixing failing functional test (hopefully)
* Minor style fix
* Fixing EUI text, rendering empty screen OR the panels
* Fixing empty screen in fullscreen mode
* Update snapshot
* Trying to render empty screen from Angular controller
* refactor: 💡 don't pass renderEmpty through inputs
And make sure isEmptyState is not stale.
* Fixing tests after Vadim's commit
* Removing unnecessary isEmptyStateProps
* Skipping failing test
* Removing unnecessary en.json file
* Re-adding emptyState, reintroducing functional test
* Fixing ja-JP file
* Undoing my thing to the functional test
---
.../dashboard_empty_screen.test.tsx.snap | 364 +++++++++++++-----
.../__tests__/dashboard_empty_screen.test.tsx | 10 +-
.../public/dashboard/_dashboard_app.scss | 6 +-
.../kibana/public/dashboard/application.ts | 1 -
.../public/dashboard/dashboard_app.html | 18 -
.../dashboard/dashboard_app_controller.tsx | 49 ++-
.../dashboard/dashboard_empty_screen.tsx | 73 ++--
.../dashboard_empty_screen_directive.ts | 30 --
.../public/dashboard/top_nav/top_nav_ids.ts | 1 +
.../public/embeddable/dashboard_container.tsx | 4 +-
.../embeddable/grid/_dashboard_grid.scss | 2 +-
.../viewport/dashboard_viewport.test.tsx | 51 +++
.../viewport/dashboard_viewport.tsx | 59 ++-
.../public/lib/containers/container.ts | 1 +
.../public/lib/embeddables/i_embeddable.ts | 2 +-
.../apps/dashboard/full_screen_mode.js | 1 -
.../public/does_inherit_time_range.ts | 4 +
.../translations/translations/ja-JP.json | 2 +-
18 files changed, 461 insertions(+), 217 deletions(-)
delete mode 100644 src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen_directive.ts
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/__tests__/__snapshots__/dashboard_empty_screen.test.tsx.snap b/src/legacy/core_plugins/kibana/public/dashboard/__tests__/__snapshots__/dashboard_empty_screen.test.tsx.snap
index 07e4173d5323f..8410040a0100d 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/__tests__/__snapshots__/dashboard_empty_screen.test.tsx.snap
+++ b/src/legacy/core_plugins/kibana/public/dashboard/__tests__/__snapshots__/dashboard_empty_screen.test.tsx.snap
@@ -193,78 +193,160 @@ exports[`DashboardEmptyScreen renders correctly with visualize paragraph 1`] = `
textComponent={Symbol(react.fragment)}
>
-
-
-
-
-
-
- This dashboard is empty. Let’s fill it up!
-
-
-
- Click the
-
-
- Add
-
-
- button in the menu bar above to add a visualization to the dashboard.
-
-
-
-
- visit the Visualize app
- ,
+ "maxWidth": "36em",
}
}
>
- If you haven't set up any visualizations yet,
-
- visit the Visualize app
-
- to create your first visualization
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This dashboard is empty. Let’s fill it up!
+
+
+
+
+
+
+
+
+
+ Click the
+
+
+ Add
+
+
+ button in the menu bar above to add a visualization to the dashboard.
+
+
+
+
+
+
+
+
+
+
+ visit the Visualize app
+ ,
+ }
+ }
+ >
+ If you haven't set up any visualizations yet,
+
+ visit the Visualize app
+
+ to create your first visualization
+
+
+
+
+
+
+
+
+
+
+
@@ -464,51 +546,119 @@ exports[`DashboardEmptyScreen renders correctly without visualize paragraph 1`]
textComponent={Symbol(react.fragment)}
>
-
-
-
-
-
-
- This dashboard is empty. Let’s fill it up!
-
-
-
- Click the
-
-
- Edit
-
-
- button in the menu bar above to start working on your new dashboard.
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This dashboard is empty. Let’s fill it up!
+
+
+
+
+
+
+
+
+
+ Click the
+
+
+ Edit
+
+
+ button in the menu bar above to start working on your new dashboard.
+
+
+
+
+
+
+
+
+
+
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/__tests__/dashboard_empty_screen.test.tsx b/src/legacy/core_plugins/kibana/public/dashboard/__tests__/dashboard_empty_screen.test.tsx
index a4604d17ddecd..69bdcf59bb227 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/__tests__/dashboard_empty_screen.test.tsx
+++ b/src/legacy/core_plugins/kibana/public/dashboard/__tests__/dashboard_empty_screen.test.tsx
@@ -18,7 +18,9 @@
*/
import React from 'react';
import { mountWithIntl } from 'test_utils/enzyme_helpers';
-import { DashboardEmptyScreen, Props } from '../dashboard_empty_screen';
+import { DashboardEmptyScreen, DashboardEmptyScreenProps } from '../dashboard_empty_screen';
+// @ts-ignore
+import { findTestSubject } from '@elastic/eui/lib/test';
describe('DashboardEmptyScreen', () => {
const defaultProps = {
@@ -26,7 +28,7 @@ describe('DashboardEmptyScreen', () => {
onLinkClick: jest.fn(),
};
- function mountComponent(props?: Props) {
+ function mountComponent(props?: DashboardEmptyScreenProps) {
const compProps = props || defaultProps;
const comp = mountWithIntl( );
return comp;
@@ -35,14 +37,14 @@ describe('DashboardEmptyScreen', () => {
test('renders correctly with visualize paragraph', () => {
const component = mountComponent();
expect(component).toMatchSnapshot();
- const paragraph = component.find('.linkToVisualizeParagraph');
+ const paragraph = findTestSubject(component, 'linkToVisualizeParagraph');
expect(paragraph.length).toBe(1);
});
test('renders correctly without visualize paragraph', () => {
const component = mountComponent({ ...defaultProps, ...{ showLinkToVisualize: false } });
expect(component).toMatchSnapshot();
- const paragraph = component.find('.linkToVisualizeParagraph');
+ const paragraph = findTestSubject(component, 'linkToVisualizeParagraph');
expect(paragraph.length).toBe(0);
});
});
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/_dashboard_app.scss b/src/legacy/core_plugins/kibana/public/dashboard/_dashboard_app.scss
index 14c35759d70a9..d9eadf6c0e37d 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/_dashboard_app.scss
+++ b/src/legacy/core_plugins/kibana/public/dashboard/_dashboard_app.scss
@@ -6,9 +6,5 @@
.dshStartScreen {
text-align: center;
- padding: $euiSize;
-
- > * {
- max-width: 36em !important;
- }
+ padding: $euiSizeS;
}
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/application.ts b/src/legacy/core_plugins/kibana/public/dashboard/application.ts
index b58325a77e61e..ef1bcab589c4a 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/application.ts
+++ b/src/legacy/core_plugins/kibana/public/dashboard/application.ts
@@ -131,7 +131,6 @@ function createLocalAngularModule(core: AppMountContext['core'], navigation: Nav
'app/dashboard/State',
'app/dashboard/ConfirmModal',
'app/dashboard/icon',
- 'app/dashboard/emptyScreen',
]);
return dashboardAngularModule;
}
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html
index c7fd8600b73bb..3cf8932958b6d 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html
+++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html
@@ -48,24 +48,6 @@
>
-
-
{{screenTitle}}
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx
index 7eac251a532c7..3b336ebfc11fe 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx
+++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx
@@ -21,9 +21,10 @@ import _ from 'lodash';
import { i18n } from '@kbn/i18n';
import React from 'react';
import angular from 'angular';
-import { uniq } from 'lodash';
+import { uniq, noop } from 'lodash';
import { Subscription } from 'rxjs';
+import { DashboardEmptyScreen, DashboardEmptyScreenProps } from './dashboard_empty_screen';
import {
subscribeWithScope,
@@ -41,8 +42,6 @@ import {
import { FilterStateManager, IndexPattern } from '../../../data/public';
import { Query, SavedQuery, IndexPatternsContract } from '../../../../../plugins/data/public';
-import './dashboard_empty_screen_directive';
-
import {
DashboardContainer,
DASHBOARD_CONTAINER_TYPE,
@@ -143,6 +142,16 @@ export class DashboardAppController {
}
$scope.showSaveQuery = dashboardCapabilities.saveQuery as boolean;
+ $scope.getShouldShowEditHelp = () =>
+ !dashboardStateManager.getPanels().length &&
+ dashboardStateManager.getIsEditMode() &&
+ !dashboardConfig.getHideWriteControls();
+
+ $scope.getShouldShowViewHelp = () =>
+ !dashboardStateManager.getPanels().length &&
+ dashboardStateManager.getIsViewMode() &&
+ !dashboardConfig.getHideWriteControls();
+
const updateIndexPatterns = (container?: DashboardContainer) => {
if (!container || isErrorEmbeddable(container)) {
return;
@@ -171,6 +180,17 @@ export class DashboardAppController {
}
};
+ const getEmptyScreenProps = (shouldShowEditHelp: boolean): DashboardEmptyScreenProps => {
+ const emptyScreenProps: DashboardEmptyScreenProps = {
+ onLinkClick: shouldShowEditHelp ? $scope.showAddPanel : $scope.enterEditMode,
+ showLinkToVisualize: shouldShowEditHelp,
+ };
+ if (shouldShowEditHelp) {
+ emptyScreenProps.onVisualizeClick = noop;
+ }
+ return emptyScreenProps;
+ };
+
const getDashboardInput = (): DashboardContainerInput => {
const embeddablesMap: {
[key: string]: DashboardPanelState;
@@ -182,6 +202,8 @@ export class DashboardAppController {
if (dashboardContainer && !isErrorEmbeddable(dashboardContainer)) {
expandedPanelId = dashboardContainer.getInput().expandedPanelId;
}
+ const shouldShowEditHelp = $scope.getShouldShowEditHelp();
+ const shouldShowViewHelp = $scope.getShouldShowViewHelp();
return {
id: dashboardStateManager.savedDashboard.id || '',
filters: queryFilter.getFilters(),
@@ -194,6 +216,7 @@ export class DashboardAppController {
viewMode: dashboardStateManager.getViewMode(),
panels: embeddablesMap,
isFullScreenMode: dashboardStateManager.getFullScreenMode(),
+ isEmptyState: shouldShowEditHelp || shouldShowViewHelp,
useMargins: dashboardStateManager.getUseMargins(),
lastReloadRequestTime,
title: dashboardStateManager.getTitle(),
@@ -234,6 +257,15 @@ export class DashboardAppController {
if (!isErrorEmbeddable(container)) {
dashboardContainer = container;
+ dashboardContainer.renderEmpty = () => {
+ const shouldShowEditHelp = $scope.getShouldShowEditHelp();
+ const shouldShowViewHelp = $scope.getShouldShowViewHelp();
+ const isEmptyState = shouldShowEditHelp || shouldShowViewHelp;
+ return isEmptyState ? (
+
+ ) : null;
+ };
+
updateIndexPatterns(dashboardContainer);
outputSubscription = dashboardContainer.getOutput$().subscribe(() => {
@@ -334,15 +366,6 @@ export class DashboardAppController {
updateBreadcrumbs();
dashboardStateManager.registerChangeListener(updateBreadcrumbs);
- $scope.getShouldShowEditHelp = () =>
- !dashboardStateManager.getPanels().length &&
- dashboardStateManager.getIsEditMode() &&
- !dashboardConfig.getHideWriteControls();
- $scope.getShouldShowViewHelp = () =>
- !dashboardStateManager.getPanels().length &&
- dashboardStateManager.getIsViewMode() &&
- !dashboardConfig.getHideWriteControls();
-
const getChangesFromAppStateForContainerState = () => {
const appStateDashboardInput = getDashboardInput();
if (!dashboardContainer || isErrorEmbeddable(dashboardContainer)) {
@@ -729,6 +752,8 @@ export class DashboardAppController {
}
};
+ navActions[TopNavIds.VISUALIZE] = async () => {};
+
navActions[TopNavIds.OPTIONS] = anchorElement => {
showOptionsPopover({
anchorElement,
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx
index d5a4e6e6a325d..234228ba4166a 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx
+++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx
@@ -18,29 +18,43 @@
*/
import React from 'react';
import { I18nProvider, FormattedMessage } from '@kbn/i18n/react';
-import { EuiIcon, EuiLink } from '@elastic/eui';
+import {
+ EuiIcon,
+ EuiLink,
+ EuiSpacer,
+ EuiPageContent,
+ EuiPageBody,
+ EuiPage,
+ EuiText,
+} from '@elastic/eui';
import * as constants from './dashboard_empty_screen_constants';
-export interface Props {
+export interface DashboardEmptyScreenProps {
showLinkToVisualize: boolean;
onLinkClick: () => void;
+ onVisualizeClick?: () => void;
}
-export function DashboardEmptyScreen({ showLinkToVisualize, onLinkClick }: Props) {
+export function DashboardEmptyScreen({
+ showLinkToVisualize,
+ onLinkClick,
+}: DashboardEmptyScreenProps) {
const linkToVisualizeParagraph = (
-
-
- {constants.visualizeAppLinkTest}
-
- ),
- }}
- />
-
+
+
+
+ {constants.visualizeAppLinkTest}
+
+ ),
+ }}
+ />
+
+
);
const paragraph = (
description1: string,
@@ -50,15 +64,15 @@ export function DashboardEmptyScreen({ showLinkToVisualize, onLinkClick }: Props
dataTestSubj?: string
) => {
return (
-
-
+
+
{description1}
{linkText}
{description2}
-
-
+
+
);
};
const addVisualizationParagraph = (
@@ -70,6 +84,7 @@ export function DashboardEmptyScreen({ showLinkToVisualize, onLinkClick }: Props
constants.addVisualizationLinkAriaLabel,
'emptyDashboardAddPanelButton'
)}
+
{linkToVisualizeParagraph}
);
@@ -81,11 +96,19 @@ export function DashboardEmptyScreen({ showLinkToVisualize, onLinkClick }: Props
);
return (
-
-
- {constants.fillDashboardTitle}
- {showLinkToVisualize ? addVisualizationParagraph : enterEditModeParagraph}
-
+
+
+
+
+
+
+ {constants.fillDashboardTitle}
+
+
+ {showLinkToVisualize ? addVisualizationParagraph : enterEditModeParagraph}
+
+
+
);
}
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen_directive.ts b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen_directive.ts
deleted file mode 100644
index 5ebefd817ca4a..0000000000000
--- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen_directive.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-// @ts-ignore
-import angular from 'angular';
-import { DashboardEmptyScreen } from './dashboard_empty_screen';
-
-angular
- .module('app/dashboard/emptyScreen', ['react'])
- .directive('dashboardEmptyScreen', function(reactDirective: any) {
- return reactDirective(DashboardEmptyScreen, [
- ['showLinkToVisualize', { watchDepth: 'value' }],
- ['onLinkClick', { watchDepth: 'reference' }],
- ]);
- });
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/top_nav/top_nav_ids.ts b/src/legacy/core_plugins/kibana/public/dashboard/top_nav/top_nav_ids.ts
index 9df86f2ca3cce..c67d6891c18e7 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/top_nav/top_nav_ids.ts
+++ b/src/legacy/core_plugins/kibana/public/dashboard/top_nav/top_nav_ids.ts
@@ -26,4 +26,5 @@ export const TopNavIds = {
ENTER_EDIT_MODE: 'enterEditMode',
CLONE: 'clone',
FULL_SCREEN: 'fullScreenMode',
+ VISUALIZE: 'visualize',
};
diff --git a/src/plugins/dashboard_embeddable_container/public/embeddable/dashboard_container.tsx b/src/plugins/dashboard_embeddable_container/public/embeddable/dashboard_container.tsx
index 684aa93779bc1..021a1a9d1e64a 100644
--- a/src/plugins/dashboard_embeddable_container/public/embeddable/dashboard_container.tsx
+++ b/src/plugins/dashboard_embeddable_container/public/embeddable/dashboard_container.tsx
@@ -90,6 +90,8 @@ export type DashboardReactContext = KibanaReactContext {
public readonly type = DASHBOARD_CONTAINER_TYPE;
+ public renderEmpty?: undefined | (() => React.ReactNode);
+
constructor(
initialInput: DashboardContainerInput,
private readonly options: DashboardContainerOptions,
@@ -124,7 +126,7 @@ export class DashboardContainer extends Container
-
+
,
dom
diff --git a/src/plugins/dashboard_embeddable_container/public/embeddable/grid/_dashboard_grid.scss b/src/plugins/dashboard_embeddable_container/public/embeddable/grid/_dashboard_grid.scss
index 24b813ec58964..0bd356522c7fa 100644
--- a/src/plugins/dashboard_embeddable_container/public/embeddable/grid/_dashboard_grid.scss
+++ b/src/plugins/dashboard_embeddable_container/public/embeddable/grid/_dashboard_grid.scss
@@ -34,7 +34,7 @@
.dshLayout-isMaximizedPanel {
height: 100% !important; /* 1. */
width: 100%;
- position: absolute;
+ position: absolute !important;
}
/**
diff --git a/src/plugins/dashboard_embeddable_container/public/embeddable/viewport/dashboard_viewport.test.tsx b/src/plugins/dashboard_embeddable_container/public/embeddable/viewport/dashboard_viewport.test.tsx
index a2f7b8dc28fb0..e3d9b8552f060 100644
--- a/src/plugins/dashboard_embeddable_container/public/embeddable/viewport/dashboard_viewport.test.tsx
+++ b/src/plugins/dashboard_embeddable_container/public/embeddable/viewport/dashboard_viewport.test.tsx
@@ -121,6 +121,24 @@ test('renders DashboardViewport with no visualizations', () => {
component.unmount();
});
+test('renders DashboardEmptyScreen', () => {
+ const renderEmptyScreen = jest.fn();
+ const { props, options } = getProps({ renderEmpty: renderEmptyScreen });
+ props.container.updateInput({ isEmptyState: true });
+ const component = mount(
+
+
+
+
+
+ );
+ const dashboardEmptyScreenDiv = component.find('.dshDashboardEmptyScreen');
+ expect(dashboardEmptyScreenDiv.length).toBe(1);
+ expect(renderEmptyScreen).toHaveBeenCalled();
+
+ component.unmount();
+});
+
test('renders exit full screen button when in full screen mode', async () => {
const { props, options } = getProps();
props.container.updateInput({ isFullScreenMode: true });
@@ -153,6 +171,39 @@ test('renders exit full screen button when in full screen mode', async () => {
component.unmount();
});
+test('renders exit full screen button when in full screen mode and empty screen', async () => {
+ const renderEmptyScreen = jest.fn();
+ renderEmptyScreen.mockReturnValue(React.createElement('div'));
+ const { props, options } = getProps({ renderEmpty: renderEmptyScreen });
+ props.container.updateInput({ isEmptyState: true, isFullScreenMode: true });
+ const component = mount(
+
+
+
+
+
+ );
+ expect(
+ (component
+ .find('.dshDashboardEmptyScreen')
+ .childAt(0)
+ .type() as any).name
+ ).toBe('ExitFullScreenButton');
+
+ props.container.updateInput({ isFullScreenMode: false });
+ component.update();
+ await nextTick();
+
+ expect(
+ (component
+ .find('.dshDashboardEmptyScreen')
+ .childAt(0)
+ .type() as any).name
+ ).not.toBe('ExitFullScreenButton');
+
+ component.unmount();
+});
+
test('DashboardViewport unmount unsubscribes', async done => {
const { props, options } = getProps();
const component = mount(
diff --git a/src/plugins/dashboard_embeddable_container/public/embeddable/viewport/dashboard_viewport.tsx b/src/plugins/dashboard_embeddable_container/public/embeddable/viewport/dashboard_viewport.tsx
index 13407e5e33725..e7fd379898dd1 100644
--- a/src/plugins/dashboard_embeddable_container/public/embeddable/viewport/dashboard_viewport.tsx
+++ b/src/plugins/dashboard_embeddable_container/public/embeddable/viewport/dashboard_viewport.tsx
@@ -26,6 +26,7 @@ import { context } from '../../../../kibana_react/public';
export interface DashboardViewportProps {
container: DashboardContainer;
+ renderEmpty?: () => React.ReactNode;
}
interface State {
@@ -34,6 +35,7 @@ interface State {
title: string;
description?: string;
panels: { [key: string]: PanelState };
+ isEmptyState?: boolean;
}
export class DashboardViewport extends React.Component {
@@ -44,26 +46,40 @@ export class DashboardViewport extends React.Component {
- const { isFullScreenMode, useMargins, title, description } = this.props.container.getInput();
+ const {
+ isFullScreenMode,
+ useMargins,
+ title,
+ description,
+ isEmptyState,
+ } = this.props.container.getInput();
if (this.mounted) {
this.setState({
isFullScreenMode,
description,
useMargins,
title,
+ isEmptyState,
});
}
});
@@ -82,19 +98,33 @@ export class DashboardViewport extends React.Component
+ {isFullScreenMode && (
+
+ )}
+ {renderEmpty && renderEmpty()}
+
+ );
+ }
+
+ private renderContainerScreen() {
const { container } = this.props;
+ const { isFullScreenMode, panels, title, description, useMargins } = this.state;
return (
- {this.state.isFullScreenMode && (
+ {isFullScreenMode && (
@@ -103,4 +133,13 @@ export class DashboardViewport extends React.Component
);
}
+
+ public render() {
+ return (
+
+ {this.state.isEmptyState ? this.renderEmptyScreen() : null}
+ {this.renderContainerScreen()}
+
+ );
+ }
}
diff --git a/src/plugins/embeddable/public/lib/containers/container.ts b/src/plugins/embeddable/public/lib/containers/container.ts
index bce16747ed48e..71e7cca3552bb 100644
--- a/src/plugins/embeddable/public/lib/containers/container.ts
+++ b/src/plugins/embeddable/public/lib/containers/container.ts
@@ -240,6 +240,7 @@ export abstract class Container<
...this.input.panels,
[panelState.explicitInput.id]: panelState,
},
+ isEmptyState: false,
} as Partial);
return await this.untilEmbeddableLoaded(panelState.explicitInput.id);
diff --git a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts
index 33cb146a056cb..0197582778940 100644
--- a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts
+++ b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts
@@ -28,7 +28,7 @@ export interface EmbeddableInput {
id: string;
lastReloadRequestTime?: number;
hidePanelTitles?: boolean;
-
+ isEmptyState?: boolean;
/**
* List of action IDs that this embeddable should not render.
*/
diff --git a/test/functional/apps/dashboard/full_screen_mode.js b/test/functional/apps/dashboard/full_screen_mode.js
index e18fd47b39b16..bf549ec21a6d3 100644
--- a/test/functional/apps/dashboard/full_screen_mode.js
+++ b/test/functional/apps/dashboard/full_screen_mode.js
@@ -78,7 +78,6 @@ export default function ({ getService, getPageObjects }) {
const logoButton = await PageObjects.dashboard.getExitFullScreenLogoButton();
await logoButton.moveMouseTo();
await PageObjects.dashboard.clickExitFullScreenTextButton();
-
await retry.try(async () => {
const isChromeVisible = await PageObjects.common.isChromeVisible();
expect(isChromeVisible).to.be(true);
diff --git a/x-pack/plugins/advanced_ui_actions/public/does_inherit_time_range.ts b/x-pack/plugins/advanced_ui_actions/public/does_inherit_time_range.ts
index 4cfe581b7eac5..d1568a5ab96ce 100644
--- a/x-pack/plugins/advanced_ui_actions/public/does_inherit_time_range.ts
+++ b/x-pack/plugins/advanced_ui_actions/public/does_inherit_time_range.ts
@@ -17,6 +17,10 @@ export function doesInheritTimeRange(embeddable: Embeddable) {
// Note: this logic might not work in a container nested world... the explicit input
// may be on the root... or any of the interim parents.
+ // if it's a dashboard emptys screen, there will be no embeddable
+ if (!parent.getInput().panels[embeddable.id]) {
+ return false;
+ }
// If there is no explicit input defined on the parent then this embeddable inherits the
// time range from whatever the time range of the parent is.
return parent.getInput().panels[embeddable.id].explicitInput.timeRange === undefined;
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index d51332c65aa54..55147c7863d1f 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -12736,4 +12736,4 @@
"xpack.licensing.welcomeBanner.licenseIsExpiredDescription.updateYourLicenseLinkText": "ライセンスを更新",
"xpack.licensing.welcomeBanner.licenseIsExpiredTitle": "ご使用の {licenseType} ライセンスは期限切れです"
}
-}
+}
\ No newline at end of file
From 5217dfd731726aa0c3ce39436b7a5018ff2aa466 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juan=20=C3=81lvarez?=
Date: Tue, 10 Dec 2019 16:11:58 +0100
Subject: [PATCH 02/24] update apm index pattern (#52629)
---
.../core_plugins/kibana/server/tutorials/apm/index_pattern.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/legacy/core_plugins/kibana/server/tutorials/apm/index_pattern.json b/src/legacy/core_plugins/kibana/server/tutorials/apm/index_pattern.json
index 69a165c09c2f9..9001613623ccb 100644
--- a/src/legacy/core_plugins/kibana/server/tutorials/apm/index_pattern.json
+++ b/src/legacy/core_plugins/kibana/server/tutorials/apm/index_pattern.json
@@ -1,7 +1,7 @@
{
"attributes": {
"fieldFormatMap": "{\"client.bytes\":{\"id\":\"bytes\"},\"client.nat.port\":{\"id\":\"string\"},\"client.port\":{\"id\":\"string\"},\"destination.bytes\":{\"id\":\"bytes\"},\"destination.nat.port\":{\"id\":\"string\"},\"destination.port\":{\"id\":\"string\"},\"event.duration\":{\"id\":\"duration\",\"params\":{\"inputFormat\":\"nanoseconds\",\"outputFormat\":\"asMilliseconds\",\"outputPrecision\":1}},\"event.sequence\":{\"id\":\"string\"},\"event.severity\":{\"id\":\"string\"},\"http.request.body.bytes\":{\"id\":\"bytes\"},\"http.request.bytes\":{\"id\":\"bytes\"},\"http.response.body.bytes\":{\"id\":\"bytes\"},\"http.response.bytes\":{\"id\":\"bytes\"},\"http.response.status_code\":{\"id\":\"string\"},\"log.syslog.facility.code\":{\"id\":\"string\"},\"log.syslog.priority\":{\"id\":\"string\"},\"network.bytes\":{\"id\":\"bytes\"},\"package.size\":{\"id\":\"string\"},\"process.pgid\":{\"id\":\"string\"},\"process.pid\":{\"id\":\"string\"},\"process.ppid\":{\"id\":\"string\"},\"process.thread.id\":{\"id\":\"string\"},\"server.bytes\":{\"id\":\"bytes\"},\"server.nat.port\":{\"id\":\"string\"},\"server.port\":{\"id\":\"string\"},\"source.bytes\":{\"id\":\"bytes\"},\"source.nat.port\":{\"id\":\"string\"},\"source.port\":{\"id\":\"string\"},\"system.cpu.total.norm.pct\":{\"id\":\"percent\"},\"system.memory.actual.free\":{\"id\":\"bytes\"},\"system.memory.total\":{\"id\":\"bytes\"},\"system.process.cpu.total.norm.pct\":{\"id\":\"percent\"},\"system.process.memory.rss.bytes\":{\"id\":\"bytes\"},\"system.process.memory.size\":{\"id\":\"bytes\"},\"url.port\":{\"id\":\"string\"},\"view spans\":{\"id\":\"url\",\"params\":{\"labelTemplate\":\"View Spans\"}}}",
- "fields": "[{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"@timestamp\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tags\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.ephemeral_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.nat.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.group.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.account.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.availability_zone\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.instance.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.instance.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.machine.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.provider\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.region\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.image.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.image.tag\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.runtime\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.nat.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.group.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.class\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.data\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.ttl\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.header_flags\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.op_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.class\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.subdomain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.resolved_ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.response_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"ecs.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":4,\"doc_values\":true,\"indexed\":true,\"name\":\"error.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.stack_trace\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.action\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.category\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.created\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.dataset\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.duration\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.end\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.kind\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.module\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.outcome\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.provider\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.risk_score\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.risk_score_norm\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.sequence\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.severity\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.start\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.timezone\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.accessed\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.created\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.ctime\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.device\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.directory\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.extension\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.gid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.group\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.hash.sha512\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.inode\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.mode\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.mtime\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.owner\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.target_path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.uid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"group.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"hash.sha512\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.architecture\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.uptime\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.group.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.body.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.body.content\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.method\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.referrer\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.body.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.body.content\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.status_code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.level\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.logger\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.origin.file.line\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.origin.file.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.origin.function\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.facility.code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.facility.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.priority\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.severity.code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.severity.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.application\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.community_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.direction\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.forwarded_ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.iana_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.protocol\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.transport\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.product\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.serial_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.vendor\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"organization.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.architecture\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.checksum\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.install_scope\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.installed\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.license\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.args\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.executable\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.sha512\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pgid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.ppid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.start\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.thread.id\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.thread.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.title\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.uptime\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.working_directory\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"related.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.nat.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.group.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.ephemeral_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.node.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.state\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.nat.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.group.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.framework\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.tactic.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.tactic.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.tactic.reference\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.technique.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.technique.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.technique.reference\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tracing.trace.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tracing.transaction.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.extension\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.fragment\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.password\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.query\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.scheme\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.username\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.device.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"fields\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"timeseries.instance\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.project.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.image.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"docker.container.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.containerized\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.build\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.codename\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.pod.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.pod.uid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.namespace\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.node.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.labels.*\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.annotations.*\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.replicaset.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.deployment.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.statefulset.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.container.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.container.image\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"processor.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"processor.event\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"timestamp.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"enabled\":false,\"indexed\":false,\"name\":\"http.request.headers\",\"scripted\":false,\"searchable\":false},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.finished\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"enabled\":false,\"indexed\":false,\"name\":\"http.response.headers\",\"scripted\":false,\"searchable\":false},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.environment\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.language.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.language.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.runtime.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.runtime.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.framework.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.framework.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.sampled\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.duration.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.duration.sum.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.self_time.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.self_time.sum.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.breakdown.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.subtype\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.self_time.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.self_time.sum.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"trace.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"parent.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.listening\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.version_major\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.original.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"experimental\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.culprit\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.grouping_key\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.module\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":4,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.handled\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.level\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.logger_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.param_message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.cpu.total.norm.pct\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.memory.total\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.memory.actual.free\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.cpu.total.norm.pct\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.memory.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.memory.rss.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.service.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.service.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.bundle_filepath\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"view spans\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.action\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.start.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.duration.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.sync\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.db.link\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.duration.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.result\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.marks\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.marks.*.*\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.span_count.dropped\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_id\",\"scripted\":false,\"searchable\":false,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_index\",\"scripted\":false,\"searchable\":false,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_score\",\"scripted\":false,\"searchable\":false,\"type\":\"number\"}]",
+ "fields": "[{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"@timestamp\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tags\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.ephemeral_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.nat.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.group.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.account.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.availability_zone\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.instance.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.instance.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.machine.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.provider\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.region\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.image.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.image.tag\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.runtime\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.nat.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.group.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.class\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.data\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.ttl\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.header_flags\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.op_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.class\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.subdomain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.resolved_ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.response_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"ecs.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":4,\"doc_values\":true,\"indexed\":true,\"name\":\"error.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.stack_trace\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.action\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.category\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.created\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.dataset\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.duration\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.end\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.kind\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.module\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.outcome\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.provider\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.risk_score\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.risk_score_norm\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.sequence\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.severity\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.start\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.timezone\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.accessed\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.created\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.ctime\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.device\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.directory\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.extension\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.gid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.group\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.hash.sha512\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.inode\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.mode\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.mtime\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.owner\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.target_path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.uid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"group.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"hash.sha512\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.architecture\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.uptime\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.group.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.body.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.body.content\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.method\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.referrer\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.body.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.body.content\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.status_code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.level\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.logger\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.origin.file.line\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.origin.file.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.origin.function\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.facility.code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.facility.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.priority\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.severity.code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.severity.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.application\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.community_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.direction\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.forwarded_ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.iana_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.protocol\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.transport\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.product\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.serial_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.vendor\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"organization.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.architecture\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.checksum\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.install_scope\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.installed\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.license\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.args\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.executable\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.sha512\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pgid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.ppid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.start\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.thread.id\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.thread.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.title\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.uptime\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.working_directory\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"related.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.nat.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.group.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.ephemeral_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.node.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.state\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.nat.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.group.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.framework\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.tactic.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.tactic.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.tactic.reference\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.technique.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.technique.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.technique.reference\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tracing.trace.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tracing.transaction.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.extension\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.fragment\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.password\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.query\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.scheme\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.username\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.device.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"fields\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"timeseries.instance\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.project.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.image.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"docker.container.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.containerized\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.build\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.codename\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.pod.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.pod.uid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.namespace\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.node.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.labels.*\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.annotations.*\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.replicaset.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.deployment.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.statefulset.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.container.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.container.image\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"processor.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"processor.event\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"timestamp.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"enabled\":false,\"indexed\":false,\"name\":\"http.request.headers\",\"scripted\":false,\"searchable\":false},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.finished\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"enabled\":false,\"indexed\":false,\"name\":\"http.response.headers\",\"scripted\":false,\"searchable\":false},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.environment\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.language.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.language.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.runtime.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.runtime.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.framework.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.framework.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.sampled\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.duration.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.duration.sum.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.self_time.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.self_time.sum.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.breakdown.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.subtype\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.self_time.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.self_time.sum.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"trace.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"parent.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.listening\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.version_major\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.original.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"experimental\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.culprit\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.grouping_key\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.module\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":4,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.handled\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.level\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.logger_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.param_message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.cpu.total.norm.pct\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.memory.total\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.memory.actual.free\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.cpu.total.norm.pct\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.memory.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.memory.rss.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.cpu.ns\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.samples.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.alloc_objects.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.alloc_space.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.inuse_objects.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.inuse_space.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.duration\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.top.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.top.function\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.top.filename\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.top.line\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.stack.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.stack.function\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.stack.filename\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.stack.line\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.service.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.service.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.bundle_filepath\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"view spans\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.action\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.start.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.duration.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.sync\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.db.link\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.duration.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.result\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.marks\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.marks.*.*\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.span_count.dropped\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_id\",\"scripted\":false,\"searchable\":false,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_index\",\"scripted\":false,\"searchable\":false,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_score\",\"scripted\":false,\"searchable\":false,\"type\":\"number\"}]",
"sourceFilters": "[{\"value\":\"sourcemap.sourcemap\"}]",
"timeFieldName": "@timestamp"
},
From 6ea07cbb9cfa01bc428da29c2d2beedb73594f8a Mon Sep 17 00:00:00 2001
From: Frank Hassanabad
Date: Tue, 10 Dec 2019 08:43:04 -0700
Subject: [PATCH 03/24] [SIEM][Detection Engine] Renaming and moving of folders
and files (#52587)
## Summary
* Creates several folders
* Moves schema into smaller files
* Moves `utils.ts` in smaller files
* Splits apart the types to not be in one giant file but rather cascade bottom up
### Checklist
Use ~~strikethroughs~~ to remove checklist items you don't feel are applicable to this PR.
~~- [ ] This was checked for cross-browser compatibility, [including a check against IE11](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility)~~
~~- [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/master/packages/kbn-i18n/README.md)~~
~~- [ ] [Documentation](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#writing-documentation) was added for features that require explanation or tutorials~~
- [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios
~~- [ ] This was checked for [keyboard-only and screenreader accessibility](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Accessibility_testing_checklist)~~
### For maintainers
~~- [ ] This was checked for breaking API changes and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)~~
- [x] This includes a feature addition or change that requires a release note and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)
---
.../plugins/siem/server/kibana.index.ts | 16 +-
.../lib/detection_engine/alerts/types.ts | 264 --
.../lib/detection_engine/alerts/utils.test.ts | 1107 ---------
.../lib/detection_engine/alerts/utils.ts | 408 ----
.../routes/__mocks__/request_responses.ts | 4 +-
.../{ => rules}/create_rules_route.test.ts | 6 +-
.../routes/{ => rules}/create_rules_route.ts | 17 +-
.../{ => rules}/delete_rules_route.test.ts | 6 +-
.../routes/{ => rules}/delete_rules_route.ts | 13 +-
.../{ => rules}/find_rules_route.test.ts | 6 +-
.../routes/{ => rules}/find_rules_route.ts | 13 +-
.../{ => rules}/read_rules_route.test.ts | 6 +-
.../routes/{ => rules}/read_rules_route.ts | 13 +-
.../detection_engine/routes/rules/types.ts | 11 +
.../{ => rules}/update_rules_route.test.ts | 6 +-
.../routes/{ => rules}/update_rules_route.ts | 13 +-
.../routes/rules/utils.test.ts | 496 ++++
.../detection_engine/routes/rules/utils.ts | 76 +
.../detection_engine/routes/schemas.test.ts | 2133 -----------------
.../lib/detection_engine/routes/schemas.ts | 162 --
.../schemas/create_rules_schema.test.ts | 1047 ++++++++
.../routes/schemas/create_rules_schema.ts | 67 +
.../routes/schemas/find_rules_schema.test.ts | 136 ++
.../routes/schemas/find_rules_schema.ts | 24 +
.../routes/schemas/query_rules_schema.test.ts | 32 +
.../routes/schemas/query_rules_schema.ts | 16 +
.../routes/schemas/schemas.ts | 79 +
.../schemas/set_signal_status_schema.test.ts | 66 +
.../schemas/set_signal_status_schema.ts | 17 +
.../schemas/update_rules_schema.test.ts | 869 +++++++
.../routes/schemas/update_rules_schema.ts | 63 +
.../signals/open_close_signals_route.ts | 4 +-
.../lib/detection_engine/routes/utils.test.ts | 488 +---
.../lib/detection_engine/routes/utils.ts | 68 -
.../{alerts => rules}/create_rules.ts | 0
.../{alerts => rules}/delete_rules.ts | 0
.../{alerts => rules}/find_rules.test.ts | 0
.../{alerts => rules}/find_rules.ts | 0
.../{alerts => rules}/read_rules.test.ts | 0
.../{alerts => rules}/read_rules.ts | 0
.../lib/detection_engine/rules/types.ts | 102 +
.../{alerts => rules}/update_rules.test.ts | 0
.../{alerts => rules}/update_rules.ts | 0
.../__mocks__/es_results.ts | 19 +-
.../signals/build_bulk_body.test.ts | 284 +++
.../signals/build_bulk_body.ts | 56 +
.../signals/build_event_type_signal.test.ts | 47 +
.../signals/build_event_type_signal.ts | 15 +
.../build_events_query.test.ts | 0
.../{alerts => signals}/build_events_query.ts | 0
.../signals/build_rule.test.ts | 156 ++
.../detection_engine/signals/build_rule.ts | 59 +
.../signals/build_signal.test.ts | 111 +
.../detection_engine/signals/build_signal.ts | 26 +
.../{alerts => signals}/get_filter.test.ts | 2 +-
.../{alerts => signals}/get_filter.ts | 2 +-
.../get_input_output_index.test.ts | 0
.../get_input_output_index.ts | 0
.../signals/search_after_bulk_create.test.ts | 286 +++
.../signals/search_after_bulk_create.ts | 135 ++
.../signal_rule_alert_type.ts} | 10 +-
.../signals/single_bulk_create.test.ts | 230 ++
.../signals/single_bulk_create.ts | 106 +
.../signals/single_search_after.test.ts | 73 +
.../signals/single_search_after.ts | 52 +
.../lib/detection_engine/signals/types.ts | 123 +
.../lib/detection_engine/signals/utils.ts | 16 +
.../siem/server/lib/detection_engine/types.ts | 67 +
.../legacy/plugins/siem/server/lib/types.ts | 20 -
69 files changed, 5029 insertions(+), 4720 deletions(-)
delete mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/types.ts
delete mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/utils.test.ts
delete mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/utils.ts
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/{ => rules}/create_rules_route.test.ts (96%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/{ => rules}/create_rules_route.ts (85%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/{ => rules}/delete_rules_route.test.ts (96%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/{ => rules}/delete_rules_route.ts (78%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/{ => rules}/find_rules_route.test.ts (94%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/{ => rules}/find_rules_route.ts (78%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/{ => rules}/read_rules_route.test.ts (94%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/{ => rules}/read_rules_route.ts (78%)
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/types.ts
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/{ => rules}/update_rules_route.test.ts (97%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/{ => rules}/update_rules_route.ts (84%)
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.test.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.ts
delete mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.test.ts
delete mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/create_rules_schema.test.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/create_rules_schema.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/find_rules_schema.test.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/find_rules_schema.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/query_rules_schema.test.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/query_rules_schema.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/schemas.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/set_signal_status_schema.test.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/set_signal_status_schema.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/update_rules_schema.test.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/update_rules_schema.ts
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts => rules}/create_rules.ts (100%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts => rules}/delete_rules.ts (100%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts => rules}/find_rules.test.ts (100%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts => rules}/find_rules.ts (100%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts => rules}/read_rules.test.ts (100%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts => rules}/read_rules.ts (100%)
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts => rules}/update_rules.test.ts (100%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts => rules}/update_rules.ts (100%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts => signals}/__mocks__/es_results.ts (94%)
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_bulk_body.test.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_bulk_body.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_event_type_signal.test.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_event_type_signal.ts
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts => signals}/build_events_query.test.ts (100%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts => signals}/build_events_query.ts (100%)
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_rule.test.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_rule.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_signal.test.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_signal.ts
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts => signals}/get_filter.test.ts (99%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts => signals}/get_filter.ts (98%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts => signals}/get_input_output_index.test.ts (100%)
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts => signals}/get_input_output_index.ts (100%)
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.test.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.ts
rename x-pack/legacy/plugins/siem/server/lib/detection_engine/{alerts/rules_alert_type.ts => signals/signal_rule_alert_type.ts} (96%)
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.test.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_search_after.test.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_search_after.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/types.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/utils.ts
create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/types.ts
diff --git a/x-pack/legacy/plugins/siem/server/kibana.index.ts b/x-pack/legacy/plugins/siem/server/kibana.index.ts
index bb0958b32fa19..f56e6b3c3f550 100644
--- a/x-pack/legacy/plugins/siem/server/kibana.index.ts
+++ b/x-pack/legacy/plugins/siem/server/kibana.index.ts
@@ -6,18 +6,18 @@
import { PluginInitializerContext } from 'src/core/server';
-import { rulesAlertType } from './lib/detection_engine/alerts/rules_alert_type';
-import { isAlertExecutor } from './lib/detection_engine/alerts/types';
-import { createRulesRoute } from './lib/detection_engine/routes/create_rules_route';
+import { signalRulesAlertType } from './lib/detection_engine/signals/signal_rule_alert_type';
+import { createRulesRoute } from './lib/detection_engine/routes/rules/create_rules_route';
import { createIndexRoute } from './lib/detection_engine/routes/index/create_index_route';
import { readIndexRoute } from './lib/detection_engine/routes/index/read_index_route';
-import { readRulesRoute } from './lib/detection_engine/routes/read_rules_route';
-import { findRulesRoute } from './lib/detection_engine/routes/find_rules_route';
-import { deleteRulesRoute } from './lib/detection_engine/routes/delete_rules_route';
-import { updateRulesRoute } from './lib/detection_engine/routes/update_rules_route';
+import { readRulesRoute } from './lib/detection_engine/routes/rules/read_rules_route';
+import { findRulesRoute } from './lib/detection_engine/routes/rules/find_rules_route';
+import { deleteRulesRoute } from './lib/detection_engine/routes/rules/delete_rules_route';
+import { updateRulesRoute } from './lib/detection_engine/routes/rules/update_rules_route';
import { setSignalsStatusRoute } from './lib/detection_engine/routes/signals/open_close_signals_route';
import { ServerFacade } from './types';
import { deleteIndexRoute } from './lib/detection_engine/routes/index/delete_index_route';
+import { isAlertExecutor } from './lib/detection_engine/signals/types';
const APP_ID = 'siem';
@@ -26,7 +26,7 @@ export const initServerWithKibana = (context: PluginInitializerContext, __legacy
const version = context.env.packageInfo.version;
if (__legacy.plugins.alerting != null) {
- const type = rulesAlertType({ logger, version });
+ const type = signalRulesAlertType({ logger, version });
if (isAlertExecutor(type)) {
__legacy.plugins.alerting.setup.registerType(type);
}
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/types.ts
deleted file mode 100644
index c9d265ebffacd..0000000000000
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/types.ts
+++ /dev/null
@@ -1,264 +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 { get } from 'lodash/fp';
-
-import { SIGNALS_ID } from '../../../../common/constants';
-import {
- Alert,
- AlertType,
- State,
- AlertExecutorOptions,
-} from '../../../../../alerting/server/types';
-import { AlertsClient } from '../../../../../alerting/server/alerts_client';
-import { ActionsClient } from '../../../../../actions/server/actions_client';
-import { RequestFacade } from '../../../types';
-import { SearchResponse } from '../../types';
-import { esFilters } from '../../../../../../../../src/plugins/data/server';
-
-export type PartialFilter = Partial;
-
-export interface IMitreAttack {
- id: string;
- name: string;
- reference: string;
-}
-export interface ThreatParams {
- framework: string;
- tactic: IMitreAttack;
- techniques: IMitreAttack[];
-}
-export interface RuleAlertParams {
- description: string;
- enabled: boolean;
- falsePositives: string[];
- filters: PartialFilter[] | undefined | null;
- from: string;
- immutable: boolean;
- index: string[];
- interval: string;
- ruleId: string | undefined | null;
- language: string | undefined | null;
- maxSignals: number;
- riskScore: number;
- outputIndex: string;
- name: string;
- query: string | undefined | null;
- references: string[];
- savedId: string | undefined | null;
- meta: Record | undefined | null;
- severity: string;
- tags: string[];
- to: string;
- threats: ThreatParams[] | undefined | null;
- type: 'query' | 'saved_query';
-}
-
-export type RuleAlertParamsRest = Omit<
- RuleAlertParams,
- 'ruleId' | 'falsePositives' | 'maxSignals' | 'savedId' | 'riskScore' | 'outputIndex'
-> & {
- rule_id: RuleAlertParams['ruleId'];
- false_positives: RuleAlertParams['falsePositives'];
- saved_id: RuleAlertParams['savedId'];
- max_signals: RuleAlertParams['maxSignals'];
- risk_score: RuleAlertParams['riskScore'];
- output_index: RuleAlertParams['outputIndex'];
-};
-
-export interface SignalsParams {
- signalIds: string[] | undefined | null;
- query: object | undefined | null;
- status: 'open' | 'closed';
-}
-
-export type SignalsRestParams = Omit & {
- signal_ids: SignalsParams['signalIds'];
-};
-
-export type OutputRuleAlertRest = RuleAlertParamsRest & {
- id: string;
- created_by: string | undefined | null;
- updated_by: string | undefined | null;
-};
-
-export type UpdateRuleAlertParamsRest = Partial & {
- id: string | undefined;
- rule_id: RuleAlertParams['ruleId'] | undefined;
-};
-
-export interface FindParamsRest {
- per_page: number;
- page: number;
- sort_field: string;
- sort_order: 'asc' | 'desc';
- fields: string[];
- filter: string;
-}
-
-export interface Clients {
- alertsClient: AlertsClient;
- actionsClient: ActionsClient;
-}
-
-export type RuleParams = RuleAlertParams & Clients;
-
-export type UpdateRuleParams = Partial & {
- id: string | undefined | null;
-} & Clients;
-
-export type DeleteRuleParams = Clients & {
- id: string | undefined;
- ruleId: string | undefined | null;
-};
-
-export interface FindRulesRequest extends Omit {
- query: {
- per_page: number;
- page: number;
- search?: string;
- sort_field?: string;
- filter?: string;
- fields?: string[];
- sort_order?: 'asc' | 'desc';
- };
-}
-
-export interface FindRuleParams {
- alertsClient: AlertsClient;
- perPage?: number;
- page?: number;
- sortField?: string;
- filter?: string;
- fields?: string[];
- sortOrder?: 'asc' | 'desc';
-}
-
-export interface ReadRuleParams {
- alertsClient: AlertsClient;
- id?: string | undefined | null;
- ruleId?: string | undefined | null;
-}
-
-export interface ReadRuleByRuleId {
- alertsClient: AlertsClient;
- ruleId: string;
-}
-
-export type RuleTypeParams = Omit;
-
-export type RuleAlertType = Alert & {
- id: string;
- params: RuleTypeParams;
-};
-
-export interface RulesRequest extends RequestFacade {
- payload: RuleAlertParamsRest;
-}
-
-export interface SignalsRequest extends RequestFacade {
- payload: SignalsRestParams;
-}
-
-export interface UpdateRulesRequest extends RequestFacade {
- payload: UpdateRuleAlertParamsRest;
-}
-
-export type RuleExecutorOptions = Omit & {
- params: RuleAlertParams & {
- scrollSize: number;
- scrollLock: string;
- };
-};
-
-export type SearchTypes =
- | string
- | string[]
- | number
- | number[]
- | boolean
- | boolean[]
- | object
- | object[];
-
-export interface SignalSource {
- [key: string]: SearchTypes;
- '@timestamp': string;
-}
-
-export interface BulkResponse {
- took: number;
- errors: boolean;
- items: [
- {
- create: {
- _index: string;
- _type?: string;
- _id: string;
- _version: number;
- result?: string;
- _shards?: {
- total: number;
- successful: number;
- failed: number;
- };
- _seq_no?: number;
- _primary_term?: number;
- status: number;
- error?: {
- type: string;
- reason: string;
- index_uuid?: string;
- shard: string;
- index: string;
- };
- };
- }
- ];
-}
-
-export interface MGetResponse {
- docs: GetResponse[];
-}
-export interface GetResponse {
- _index: string;
- _type: string;
- _id: string;
- _version: number;
- _seq_no: number;
- _primary_term: number;
- found: boolean;
- _source: SearchTypes;
-}
-
-export type SignalSearchResponse = SearchResponse;
-export type SignalSourceHit = SignalSearchResponse['hits']['hits'][0];
-
-export type QueryRequest = Omit & {
- query: { id: string | undefined; rule_id: string | undefined };
-};
-
-// This returns true because by default a RuleAlertTypeDefinition is an AlertType
-// since we are only increasing the strictness of params.
-export const isAlertExecutor = (obj: RuleAlertTypeDefinition): obj is AlertType => {
- return true;
-};
-
-export type RuleAlertTypeDefinition = Omit & {
- executor: ({ services, params, state }: RuleExecutorOptions) => Promise;
-};
-
-export const isAlertTypes = (obj: unknown[]): obj is RuleAlertType[] => {
- return obj.every(rule => isAlertType(rule));
-};
-
-export const isAlertType = (obj: unknown): obj is RuleAlertType => {
- return get('alertTypeId', obj) === SIGNALS_ID;
-};
-
-export const isAlertTypeArray = (objArray: unknown[]): objArray is RuleAlertType[] => {
- return objArray.length === 0 || isAlertType(objArray[0]);
-};
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/utils.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/utils.test.ts
deleted file mode 100644
index 41052ab4bbb15..0000000000000
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/utils.test.ts
+++ /dev/null
@@ -1,1107 +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 uuid from 'uuid';
-import { savedObjectsClientMock } from 'src/core/server/mocks';
-
-import { Logger } from '../../../../../../../../src/core/server';
-import {
- buildBulkBody,
- generateId,
- singleBulkCreate,
- singleSearchAfter,
- searchAfterAndBulkCreate,
- buildEventTypeSignal,
- buildSignal,
- buildRule,
-} from './utils';
-import {
- sampleDocNoSortId,
- sampleRuleAlertParams,
- sampleDocSearchResultsNoSortId,
- sampleDocSearchResultsNoSortIdNoHits,
- sampleDocSearchResultsNoSortIdNoVersion,
- sampleDocSearchResultsWithSortId,
- sampleEmptyDocSearchResults,
- repeatedSearchResultsWithSortId,
- sampleBulkCreateDuplicateResult,
- sampleRuleGuid,
- sampleRule,
- sampleIdGuid,
-} from './__mocks__/es_results';
-import { DEFAULT_SIGNALS_INDEX } from '../../../../common/constants';
-import { OutputRuleAlertRest } from './types';
-import { Signal } from '../../types';
-
-const mockLogger: Logger = {
- log: jest.fn(),
- trace: jest.fn(),
- debug: jest.fn(),
- info: jest.fn(),
- warn: jest.fn(),
- error: jest.fn(),
- fatal: jest.fn(),
-};
-
-const mockService = {
- callCluster: jest.fn(),
- alertInstanceFactory: jest.fn(),
- savedObjectsClient: savedObjectsClientMock.create(),
-};
-
-describe('utils', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- });
- describe('buildBulkBody', () => {
- test('if bulk body builds well-defined body', () => {
- const sampleParams = sampleRuleAlertParams();
- const fakeSignalSourceHit = buildBulkBody({
- doc: sampleDocNoSortId(),
- ruleParams: sampleParams,
- id: sampleRuleGuid,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- // Timestamp will potentially always be different so remove it for the test
- delete fakeSignalSourceHit['@timestamp'];
- expect(fakeSignalSourceHit).toEqual({
- someKey: 'someValue',
- event: {
- kind: 'signal',
- },
- signal: {
- parent: {
- id: sampleIdGuid,
- type: 'event',
- index: 'myFakeSignalIndex',
- depth: 1,
- },
- original_time: 'someTimeStamp',
- status: 'open',
- rule: {
- id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
- rule_id: 'rule-1',
- false_positives: [],
- max_signals: 10000,
- risk_score: 50,
- output_index: '.siem-signals',
- description: 'Detecting root and admin users',
- from: 'now-6m',
- immutable: false,
- index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
- interval: '5m',
- language: 'kuery',
- name: 'rule-name',
- query: 'user.name: root or user.name: admin',
- references: ['http://google.com'],
- severity: 'high',
- tags: ['some fake tag 1', 'some fake tag 2'],
- type: 'query',
- to: 'now',
- enabled: true,
- created_by: 'elastic',
- updated_by: 'elastic',
- },
- },
- });
- });
-
- test('if bulk body builds original_event if it exists on the event to begin with', () => {
- const sampleParams = sampleRuleAlertParams();
- const doc = sampleDocNoSortId();
- doc._source.event = {
- action: 'socket_opened',
- module: 'system',
- dataset: 'socket',
- kind: 'event',
- };
- const fakeSignalSourceHit = buildBulkBody({
- doc,
- ruleParams: sampleParams,
- id: sampleRuleGuid,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- // Timestamp will potentially always be different so remove it for the test
- delete fakeSignalSourceHit['@timestamp'];
- expect(fakeSignalSourceHit).toEqual({
- someKey: 'someValue',
- event: {
- action: 'socket_opened',
- dataset: 'socket',
- kind: 'signal',
- module: 'system',
- },
- signal: {
- original_event: {
- action: 'socket_opened',
- dataset: 'socket',
- kind: 'event',
- module: 'system',
- },
- parent: {
- id: sampleIdGuid,
- type: 'event',
- index: 'myFakeSignalIndex',
- depth: 1,
- },
- original_time: 'someTimeStamp',
- status: 'open',
- rule: {
- id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
- rule_id: 'rule-1',
- false_positives: [],
- max_signals: 10000,
- risk_score: 50,
- output_index: '.siem-signals',
- description: 'Detecting root and admin users',
- from: 'now-6m',
- immutable: false,
- index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
- interval: '5m',
- language: 'kuery',
- name: 'rule-name',
- query: 'user.name: root or user.name: admin',
- references: ['http://google.com'],
- severity: 'high',
- tags: ['some fake tag 1', 'some fake tag 2'],
- type: 'query',
- to: 'now',
- enabled: true,
- created_by: 'elastic',
- updated_by: 'elastic',
- },
- },
- });
- });
-
- test('if bulk body builds original_event if it exists on the event to begin with but no kind information', () => {
- const sampleParams = sampleRuleAlertParams();
- const doc = sampleDocNoSortId();
- doc._source.event = {
- action: 'socket_opened',
- module: 'system',
- dataset: 'socket',
- };
- const fakeSignalSourceHit = buildBulkBody({
- doc,
- ruleParams: sampleParams,
- id: sampleRuleGuid,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- // Timestamp will potentially always be different so remove it for the test
- delete fakeSignalSourceHit['@timestamp'];
- expect(fakeSignalSourceHit).toEqual({
- someKey: 'someValue',
- event: {
- action: 'socket_opened',
- dataset: 'socket',
- kind: 'signal',
- module: 'system',
- },
- signal: {
- original_event: {
- action: 'socket_opened',
- dataset: 'socket',
- module: 'system',
- },
- parent: {
- id: sampleIdGuid,
- type: 'event',
- index: 'myFakeSignalIndex',
- depth: 1,
- },
- original_time: 'someTimeStamp',
- status: 'open',
- rule: {
- id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
- rule_id: 'rule-1',
- false_positives: [],
- max_signals: 10000,
- risk_score: 50,
- output_index: '.siem-signals',
- description: 'Detecting root and admin users',
- from: 'now-6m',
- immutable: false,
- index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
- interval: '5m',
- language: 'kuery',
- name: 'rule-name',
- query: 'user.name: root or user.name: admin',
- references: ['http://google.com'],
- severity: 'high',
- tags: ['some fake tag 1', 'some fake tag 2'],
- type: 'query',
- to: 'now',
- enabled: true,
- created_by: 'elastic',
- updated_by: 'elastic',
- },
- },
- });
- });
-
- test('if bulk body builds original_event if it exists on the event to begin with with only kind information', () => {
- const sampleParams = sampleRuleAlertParams();
- const doc = sampleDocNoSortId();
- doc._source.event = {
- kind: 'event',
- };
- const fakeSignalSourceHit = buildBulkBody({
- doc,
- ruleParams: sampleParams,
- id: sampleRuleGuid,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- // Timestamp will potentially always be different so remove it for the test
- delete fakeSignalSourceHit['@timestamp'];
- expect(fakeSignalSourceHit).toEqual({
- someKey: 'someValue',
- event: {
- kind: 'signal',
- },
- signal: {
- original_event: {
- kind: 'event',
- },
- parent: {
- id: sampleIdGuid,
- type: 'event',
- index: 'myFakeSignalIndex',
- depth: 1,
- },
- original_time: 'someTimeStamp',
- status: 'open',
- rule: {
- id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
- rule_id: 'rule-1',
- false_positives: [],
- max_signals: 10000,
- risk_score: 50,
- output_index: '.siem-signals',
- description: 'Detecting root and admin users',
- from: 'now-6m',
- immutable: false,
- index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
- interval: '5m',
- language: 'kuery',
- name: 'rule-name',
- query: 'user.name: root or user.name: admin',
- references: ['http://google.com'],
- severity: 'high',
- tags: ['some fake tag 1', 'some fake tag 2'],
- type: 'query',
- to: 'now',
- enabled: true,
- created_by: 'elastic',
- updated_by: 'elastic',
- },
- },
- });
- });
- });
- describe('singleBulkCreate', () => {
- describe('create signal id gereateId', () => {
- test('two docs with same index, id, and version should have same id', () => {
- const findex = 'myfakeindex';
- const fid = 'somefakeid';
- const version = '1';
- const ruleId = 'rule-1';
- // 'myfakeindexsomefakeid1rule-1'
- const generatedHash = '342404d620be4344d6d90dd0461d1d1848aec457944d5c5f40cc0cbfedb36679';
- const firstHash = generateId(findex, fid, version, ruleId);
- const secondHash = generateId(findex, fid, version, ruleId);
- expect(firstHash).toEqual(generatedHash);
- expect(secondHash).toEqual(generatedHash);
- expect(Buffer.byteLength(firstHash, 'utf8')).toBeLessThan(512); // 512 bytes is maximum size of _id field
- expect(Buffer.byteLength(secondHash, 'utf8')).toBeLessThan(512);
- });
- test('two docs with different index, id, and version should have different id', () => {
- const findex = 'myfakeindex';
- const findex2 = 'mysecondfakeindex';
- const fid = 'somefakeid';
- const version = '1';
- const ruleId = 'rule-1';
- // 'myfakeindexsomefakeid1rule-1'
- const firstGeneratedHash =
- '342404d620be4344d6d90dd0461d1d1848aec457944d5c5f40cc0cbfedb36679';
- // 'mysecondfakeindexsomefakeid1rule-1'
- const secondGeneratedHash =
- 'a852941273f805ffe9006e574601acc8ae1148d6c0b3f7f8c4785cba8f6b768a';
- const firstHash = generateId(findex, fid, version, ruleId);
- const secondHash = generateId(findex2, fid, version, ruleId);
- expect(firstHash).toEqual(firstGeneratedHash);
- expect(secondHash).toEqual(secondGeneratedHash);
- expect(Buffer.byteLength(firstHash, 'utf8')).toBeLessThan(512); // 512 bytes is maximum size of _id field
- expect(Buffer.byteLength(secondHash, 'utf8')).toBeLessThan(512);
- expect(firstHash).not.toEqual(secondHash);
- });
- test('two docs with same index, different id, and same version should have different id', () => {
- const findex = 'myfakeindex';
- const fid = 'somefakeid';
- const fid2 = 'somefakeid2';
- const version = '1';
- const ruleId = 'rule-1';
- // 'myfakeindexsomefakeid1rule-1'
- const firstGeneratedHash =
- '342404d620be4344d6d90dd0461d1d1848aec457944d5c5f40cc0cbfedb36679';
- // 'myfakeindexsomefakeid21rule-1'
- const secondGeneratedHash =
- '7d33faea18159fd010c4b79890620e8b12cdc88ec1d370149d0e5552ce860255';
- const firstHash = generateId(findex, fid, version, ruleId);
- const secondHash = generateId(findex, fid2, version, ruleId);
- expect(firstHash).toEqual(firstGeneratedHash);
- expect(secondHash).toEqual(secondGeneratedHash);
- expect(Buffer.byteLength(firstHash, 'utf8')).toBeLessThan(512); // 512 bytes is maximum size of _id field
- expect(Buffer.byteLength(secondHash, 'utf8')).toBeLessThan(512);
- expect(firstHash).not.toEqual(secondHash);
- });
- test('two docs with same index, same id, and different version should have different id', () => {
- const findex = 'myfakeindex';
- const fid = 'somefakeid';
- const version = '1';
- const version2 = '2';
- const ruleId = 'rule-1';
- // 'myfakeindexsomefakeid1rule-1'
- const firstGeneratedHash =
- '342404d620be4344d6d90dd0461d1d1848aec457944d5c5f40cc0cbfedb36679';
- // myfakeindexsomefakeid2rule-1'
- const secondGeneratedHash =
- 'f016f3071fa9df9221d2fb2ba92389d4d388a4347c6ec7a4012c01cb1c640a40';
- const firstHash = generateId(findex, fid, version, ruleId);
- const secondHash = generateId(findex, fid, version2, ruleId);
- expect(firstHash).toEqual(firstGeneratedHash);
- expect(secondHash).toEqual(secondGeneratedHash);
- expect(Buffer.byteLength(firstHash, 'utf8')).toBeLessThan(512); // 512 bytes is maximum size of _id field
- expect(Buffer.byteLength(secondHash, 'utf8')).toBeLessThan(512);
- expect(firstHash).not.toEqual(secondHash);
- });
- test('Ensure generated id is less than 512 bytes, even for really really long strings', () => {
- const longIndexName =
- 'myfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindexmyfakeindex';
- const fid = 'somefakeid';
- const version = '1';
- const ruleId = 'rule-1';
- const firstHash = generateId(longIndexName, fid, version, ruleId);
- expect(Buffer.byteLength(firstHash, 'utf8')).toBeLessThan(512); // 512 bytes is maximum size of _id field
- });
- test('two docs with same index, same id, same version number, and different rule ids should have different id', () => {
- const findex = 'myfakeindex';
- const fid = 'somefakeid';
- const version = '1';
- const ruleId = 'rule-1';
- const ruleId2 = 'rule-2';
- // 'myfakeindexsomefakeid1rule-1'
- const firstGeneratedHash =
- '342404d620be4344d6d90dd0461d1d1848aec457944d5c5f40cc0cbfedb36679';
- // myfakeindexsomefakeid1rule-2'
- const secondGeneratedHash =
- '1eb04f997086f8b3b143d4d9b18ac178c4a7423f71a5dad9ba8b9e92603c6863';
- const firstHash = generateId(findex, fid, version, ruleId);
- const secondHash = generateId(findex, fid, version, ruleId2);
- expect(firstHash).toEqual(firstGeneratedHash);
- expect(secondHash).toEqual(secondGeneratedHash);
- expect(Buffer.byteLength(firstHash, 'utf8')).toBeLessThan(512); // 512 bytes is maximum size of _id field
- expect(Buffer.byteLength(secondHash, 'utf8')).toBeLessThan(512);
- expect(firstHash).not.toEqual(secondHash);
- });
- });
- test('create successful bulk create', async () => {
- const sampleParams = sampleRuleAlertParams();
- const sampleSearchResult = sampleDocSearchResultsNoSortId;
- mockService.callCluster.mockReturnValueOnce({
- took: 100,
- errors: false,
- items: [
- {
- fakeItemValue: 'fakeItemKey',
- },
- ],
- });
- const successfulsingleBulkCreate = await singleBulkCreate({
- someResult: sampleSearchResult(),
- ruleParams: sampleParams,
- services: mockService,
- logger: mockLogger,
- id: sampleRuleGuid,
- signalsIndex: DEFAULT_SIGNALS_INDEX,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- expect(successfulsingleBulkCreate).toEqual(true);
- });
- test('create successful bulk create with docs with no versioning', async () => {
- const sampleParams = sampleRuleAlertParams();
- const sampleSearchResult = sampleDocSearchResultsNoSortIdNoVersion;
- mockService.callCluster.mockReturnValueOnce({
- took: 100,
- errors: false,
- items: [
- {
- fakeItemValue: 'fakeItemKey',
- },
- ],
- });
- const successfulsingleBulkCreate = await singleBulkCreate({
- someResult: sampleSearchResult(),
- ruleParams: sampleParams,
- services: mockService,
- logger: mockLogger,
- id: sampleRuleGuid,
- signalsIndex: DEFAULT_SIGNALS_INDEX,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- expect(successfulsingleBulkCreate).toEqual(true);
- });
- test('create unsuccessful bulk create due to empty search results', async () => {
- const sampleParams = sampleRuleAlertParams();
- const sampleSearchResult = sampleEmptyDocSearchResults;
- mockService.callCluster.mockReturnValue(false);
- const successfulsingleBulkCreate = await singleBulkCreate({
- someResult: sampleSearchResult,
- ruleParams: sampleParams,
- services: mockService,
- logger: mockLogger,
- id: sampleRuleGuid,
- signalsIndex: DEFAULT_SIGNALS_INDEX,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- expect(successfulsingleBulkCreate).toEqual(true);
- });
- test('create successful bulk create when bulk create has errors', async () => {
- const sampleParams = sampleRuleAlertParams();
- const sampleSearchResult = sampleDocSearchResultsNoSortId;
- mockService.callCluster.mockReturnValue(sampleBulkCreateDuplicateResult);
- const successfulsingleBulkCreate = await singleBulkCreate({
- someResult: sampleSearchResult(),
- ruleParams: sampleParams,
- services: mockService,
- logger: mockLogger,
- id: sampleRuleGuid,
- signalsIndex: DEFAULT_SIGNALS_INDEX,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- expect(mockLogger.error).toHaveBeenCalled();
- expect(successfulsingleBulkCreate).toEqual(true);
- });
- });
- describe('singleSearchAfter', () => {
- test('if singleSearchAfter works without a given sort id', async () => {
- let searchAfterSortId;
- const sampleParams = sampleRuleAlertParams();
- mockService.callCluster.mockReturnValue(sampleDocSearchResultsNoSortId);
- await expect(
- singleSearchAfter({
- searchAfterSortId,
- ruleParams: sampleParams,
- services: mockService,
- logger: mockLogger,
- pageSize: 1,
- filter: undefined,
- })
- ).rejects.toThrow('Attempted to search after with empty sort id');
- });
- test('if singleSearchAfter works with a given sort id', async () => {
- const searchAfterSortId = '1234567891111';
- const sampleParams = sampleRuleAlertParams();
- mockService.callCluster.mockReturnValue(sampleDocSearchResultsWithSortId);
- const searchAfterResult = await singleSearchAfter({
- searchAfterSortId,
- ruleParams: sampleParams,
- services: mockService,
- logger: mockLogger,
- pageSize: 1,
- filter: undefined,
- });
- expect(searchAfterResult).toEqual(sampleDocSearchResultsWithSortId);
- });
- test('if singleSearchAfter throws error', async () => {
- const searchAfterSortId = '1234567891111';
- const sampleParams = sampleRuleAlertParams();
- mockService.callCluster.mockImplementation(async () => {
- throw Error('Fake Error');
- });
- await expect(
- singleSearchAfter({
- searchAfterSortId,
- ruleParams: sampleParams,
- services: mockService,
- logger: mockLogger,
- pageSize: 1,
- filter: undefined,
- })
- ).rejects.toThrow('Fake Error');
- });
- });
- describe('searchAfterAndBulkCreate', () => {
- test('if successful with empty search results', async () => {
- const sampleParams = sampleRuleAlertParams();
- const result = await searchAfterAndBulkCreate({
- someResult: sampleEmptyDocSearchResults,
- ruleParams: sampleParams,
- services: mockService,
- logger: mockLogger,
- id: sampleRuleGuid,
- signalsIndex: DEFAULT_SIGNALS_INDEX,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- pageSize: 1,
- filter: undefined,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- expect(mockService.callCluster).toHaveBeenCalledTimes(0);
- expect(result).toEqual(true);
- });
- test('if successful iteration of while loop with maxDocs', async () => {
- const sampleParams = sampleRuleAlertParams(30);
- const someGuids = Array.from({ length: 13 }).map(x => uuid.v4());
- mockService.callCluster
- .mockReturnValueOnce({
- took: 100,
- errors: false,
- items: [
- {
- fakeItemValue: 'fakeItemKey',
- },
- ],
- })
- .mockReturnValueOnce(repeatedSearchResultsWithSortId(3, 1, someGuids.slice(0, 3)))
- .mockReturnValueOnce({
- took: 100,
- errors: false,
- items: [
- {
- fakeItemValue: 'fakeItemKey',
- },
- ],
- })
- .mockReturnValueOnce(repeatedSearchResultsWithSortId(3, 1, someGuids.slice(3, 6)))
- .mockReturnValueOnce({
- took: 100,
- errors: false,
- items: [
- {
- fakeItemValue: 'fakeItemKey',
- },
- ],
- });
- const result = await searchAfterAndBulkCreate({
- someResult: repeatedSearchResultsWithSortId(3, 1, someGuids.slice(6, 9)),
- ruleParams: sampleParams,
- services: mockService,
- logger: mockLogger,
- id: sampleRuleGuid,
- signalsIndex: DEFAULT_SIGNALS_INDEX,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- pageSize: 1,
- filter: undefined,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- expect(mockService.callCluster).toHaveBeenCalledTimes(5);
- expect(result).toEqual(true);
- });
- test('if unsuccessful first bulk create', async () => {
- const someGuids = Array.from({ length: 4 }).map(x => uuid.v4());
- const sampleParams = sampleRuleAlertParams(10);
- mockService.callCluster.mockReturnValue(sampleBulkCreateDuplicateResult);
- const result = await searchAfterAndBulkCreate({
- someResult: repeatedSearchResultsWithSortId(4, 1, someGuids),
- ruleParams: sampleParams,
- services: mockService,
- logger: mockLogger,
- id: sampleRuleGuid,
- signalsIndex: DEFAULT_SIGNALS_INDEX,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- pageSize: 1,
- filter: undefined,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- expect(mockLogger.error).toHaveBeenCalled();
- expect(result).toEqual(false);
- });
- test('if unsuccessful iteration of searchAfterAndBulkCreate due to empty sort ids', async () => {
- const sampleParams = sampleRuleAlertParams();
- mockService.callCluster.mockReturnValueOnce({
- took: 100,
- errors: false,
- items: [
- {
- fakeItemValue: 'fakeItemKey',
- },
- ],
- });
- const result = await searchAfterAndBulkCreate({
- someResult: sampleDocSearchResultsNoSortId(),
- ruleParams: sampleParams,
- services: mockService,
- logger: mockLogger,
- id: sampleRuleGuid,
- signalsIndex: DEFAULT_SIGNALS_INDEX,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- pageSize: 1,
- filter: undefined,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- expect(mockLogger.error).toHaveBeenCalled();
- expect(result).toEqual(false);
- });
- test('if unsuccessful iteration of searchAfterAndBulkCreate due to empty sort ids and 0 total hits', async () => {
- const sampleParams = sampleRuleAlertParams();
- mockService.callCluster.mockReturnValueOnce({
- took: 100,
- errors: false,
- items: [
- {
- fakeItemValue: 'fakeItemKey',
- },
- ],
- });
- const result = await searchAfterAndBulkCreate({
- someResult: sampleDocSearchResultsNoSortIdNoHits(),
- ruleParams: sampleParams,
- services: mockService,
- logger: mockLogger,
- id: sampleRuleGuid,
- signalsIndex: DEFAULT_SIGNALS_INDEX,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- pageSize: 1,
- filter: undefined,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- expect(result).toEqual(true);
- });
- test('if successful iteration of while loop with maxDocs and search after returns results with no sort ids', async () => {
- const sampleParams = sampleRuleAlertParams(10);
- const someGuids = Array.from({ length: 4 }).map(x => uuid.v4());
- mockService.callCluster
- .mockReturnValueOnce({
- took: 100,
- errors: false,
- items: [
- {
- fakeItemValue: 'fakeItemKey',
- },
- ],
- })
- .mockReturnValueOnce(sampleDocSearchResultsNoSortId());
- const result = await searchAfterAndBulkCreate({
- someResult: repeatedSearchResultsWithSortId(4, 1, someGuids),
- ruleParams: sampleParams,
- services: mockService,
- logger: mockLogger,
- id: sampleRuleGuid,
- signalsIndex: DEFAULT_SIGNALS_INDEX,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- pageSize: 1,
- filter: undefined,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- expect(result).toEqual(true);
- });
- test('if successful iteration of while loop with maxDocs and search after returns empty results with no sort ids', async () => {
- const sampleParams = sampleRuleAlertParams(10);
- const someGuids = Array.from({ length: 4 }).map(x => uuid.v4());
- mockService.callCluster
- .mockReturnValueOnce({
- took: 100,
- errors: false,
- items: [
- {
- fakeItemValue: 'fakeItemKey',
- },
- ],
- })
- .mockReturnValueOnce(sampleEmptyDocSearchResults);
- const result = await searchAfterAndBulkCreate({
- someResult: repeatedSearchResultsWithSortId(4, 1, someGuids),
- ruleParams: sampleParams,
- services: mockService,
- logger: mockLogger,
- id: sampleRuleGuid,
- signalsIndex: DEFAULT_SIGNALS_INDEX,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- pageSize: 1,
- filter: undefined,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- expect(result).toEqual(true);
- });
- test('if returns false when singleSearchAfter throws an exception', async () => {
- const sampleParams = sampleRuleAlertParams(10);
- const someGuids = Array.from({ length: 4 }).map(x => uuid.v4());
- mockService.callCluster
- .mockReturnValueOnce({
- took: 100,
- errors: false,
- items: [
- {
- fakeItemValue: 'fakeItemKey',
- },
- ],
- })
- .mockImplementation(() => {
- throw Error('Fake Error');
- });
- const result = await searchAfterAndBulkCreate({
- someResult: repeatedSearchResultsWithSortId(4, 1, someGuids),
- ruleParams: sampleParams,
- services: mockService,
- logger: mockLogger,
- id: sampleRuleGuid,
- signalsIndex: DEFAULT_SIGNALS_INDEX,
- name: 'rule-name',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: '5m',
- enabled: true,
- pageSize: 1,
- filter: undefined,
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- expect(result).toEqual(false);
- });
- });
-
- describe('buildEventTypeSignal', () => {
- test('it returns the event appended of kind signal if it does not exist', () => {
- const doc = sampleDocNoSortId();
- delete doc._source.event;
- const eventType = buildEventTypeSignal(doc);
- const expected: object = { kind: 'signal' };
- expect(eventType).toEqual(expected);
- });
-
- test('it returns the event appended of kind signal if it is an empty object', () => {
- const doc = sampleDocNoSortId();
- doc._source.event = {};
- const eventType = buildEventTypeSignal(doc);
- const expected: object = { kind: 'signal' };
- expect(eventType).toEqual(expected);
- });
-
- test('it returns the event with kind signal and other properties if they exist', () => {
- const doc = sampleDocNoSortId();
- doc._source.event = {
- action: 'socket_opened',
- module: 'system',
- dataset: 'socket',
- };
- const eventType = buildEventTypeSignal(doc);
- const expected: object = {
- action: 'socket_opened',
- module: 'system',
- dataset: 'socket',
- kind: 'signal',
- };
- expect(eventType).toEqual(expected);
- });
- });
-
- describe('buildSignal', () => {
- test('it builds a signal as expected without original_event if event does not exist', () => {
- const doc = sampleDocNoSortId('d5e8eb51-a6a0-456d-8a15-4b79bfec3d71');
- delete doc._source.event;
- const rule: Partial = sampleRule();
- const signal = buildSignal(doc, rule);
- const expected: Signal = {
- parent: {
- id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71',
- type: 'event',
- index: 'myFakeSignalIndex',
- depth: 1,
- },
- original_time: 'someTimeStamp',
- status: 'open',
- rule: {
- created_by: 'elastic',
- description: 'Detecting root and admin users',
- enabled: true,
- false_positives: [],
- from: 'now-6m',
- id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
- immutable: false,
- index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
- interval: '5m',
- risk_score: 50,
- rule_id: 'rule-1',
- language: 'kuery',
- max_signals: 100,
- name: 'Detect Root/Admin Users',
- output_index: '.siem-signals',
- query: 'user.name: root or user.name: admin',
- references: ['http://www.example.com', 'https://ww.example.com'],
- severity: 'high',
- updated_by: 'elastic',
- tags: ['some fake tag 1', 'some fake tag 2'],
- to: 'now',
- type: 'query',
- },
- };
- expect(signal).toEqual(expected);
- });
-
- test('it builds a signal as expected with original_event if is present', () => {
- const doc = sampleDocNoSortId('d5e8eb51-a6a0-456d-8a15-4b79bfec3d71');
- doc._source.event = {
- action: 'socket_opened',
- dataset: 'socket',
- kind: 'event',
- module: 'system',
- };
- const rule: Partial = sampleRule();
- const signal = buildSignal(doc, rule);
- const expected: Signal = {
- parent: {
- id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71',
- type: 'event',
- index: 'myFakeSignalIndex',
- depth: 1,
- },
- original_time: 'someTimeStamp',
- original_event: {
- action: 'socket_opened',
- dataset: 'socket',
- kind: 'event',
- module: 'system',
- },
- status: 'open',
- rule: {
- created_by: 'elastic',
- description: 'Detecting root and admin users',
- enabled: true,
- false_positives: [],
- from: 'now-6m',
- id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
- immutable: false,
- index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
- interval: '5m',
- risk_score: 50,
- rule_id: 'rule-1',
- language: 'kuery',
- max_signals: 100,
- name: 'Detect Root/Admin Users',
- output_index: '.siem-signals',
- query: 'user.name: root or user.name: admin',
- references: ['http://www.example.com', 'https://ww.example.com'],
- severity: 'high',
- updated_by: 'elastic',
- tags: ['some fake tag 1', 'some fake tag 2'],
- to: 'now',
- type: 'query',
- },
- };
- expect(signal).toEqual(expected);
- });
- });
-
- describe('buildRule', () => {
- test('it builds a rule as expected with filters present', () => {
- const ruleParams = sampleRuleAlertParams();
- ruleParams.filters = [
- {
- query: 'host.name: Rebecca',
- },
- {
- query: 'host.name: Evan',
- },
- {
- query: 'host.name: Braden',
- },
- ];
- const rule = buildRule({
- ruleParams,
- name: 'some-name',
- id: sampleRuleGuid,
- enabled: false,
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: 'some interval',
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- const expected: Partial = {
- created_by: 'elastic',
- description: 'Detecting root and admin users',
- enabled: false,
- false_positives: [],
- from: 'now-6m',
- id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
- immutable: false,
- index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
- interval: 'some interval',
- language: 'kuery',
- max_signals: 10000,
- name: 'some-name',
- output_index: '.siem-signals',
- query: 'user.name: root or user.name: admin',
- references: ['http://google.com'],
- risk_score: 50,
- rule_id: 'rule-1',
- severity: 'high',
- tags: ['some fake tag 1', 'some fake tag 2'],
- to: 'now',
- type: 'query',
- updated_by: 'elastic',
- filters: [
- {
- query: 'host.name: Rebecca',
- },
- {
- query: 'host.name: Evan',
- },
- {
- query: 'host.name: Braden',
- },
- ],
- };
- expect(rule).toEqual(expected);
- });
-
- test('it omits a null value such as if enabled is null if is present', () => {
- const ruleParams = sampleRuleAlertParams();
- ruleParams.filters = undefined;
- const rule = buildRule({
- ruleParams,
- name: 'some-name',
- id: sampleRuleGuid,
- enabled: true,
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: 'some interval',
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- const expected: Partial = {
- created_by: 'elastic',
- description: 'Detecting root and admin users',
- enabled: true,
- false_positives: [],
- from: 'now-6m',
- id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
- immutable: false,
- index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
- interval: 'some interval',
- language: 'kuery',
- max_signals: 10000,
- name: 'some-name',
- output_index: '.siem-signals',
- query: 'user.name: root or user.name: admin',
- references: ['http://google.com'],
- risk_score: 50,
- rule_id: 'rule-1',
- severity: 'high',
- tags: ['some fake tag 1', 'some fake tag 2'],
- to: 'now',
- type: 'query',
- updated_by: 'elastic',
- };
- expect(rule).toEqual(expected);
- });
-
- test('it omits a null value such as if filters is undefined if is present', () => {
- const ruleParams = sampleRuleAlertParams();
- ruleParams.filters = undefined;
- const rule = buildRule({
- ruleParams,
- name: 'some-name',
- id: sampleRuleGuid,
- enabled: true,
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: 'some interval',
- tags: ['some fake tag 1', 'some fake tag 2'],
- });
- const expected: Partial = {
- created_by: 'elastic',
- description: 'Detecting root and admin users',
- enabled: true,
- false_positives: [],
- from: 'now-6m',
- id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
- immutable: false,
- index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
- interval: 'some interval',
- language: 'kuery',
- max_signals: 10000,
- name: 'some-name',
- output_index: '.siem-signals',
- query: 'user.name: root or user.name: admin',
- references: ['http://google.com'],
- risk_score: 50,
- rule_id: 'rule-1',
- severity: 'high',
- tags: ['some fake tag 1', 'some fake tag 2'],
- to: 'now',
- type: 'query',
- updated_by: 'elastic',
- };
- expect(rule).toEqual(expected);
- });
- });
-});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/utils.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/utils.ts
deleted file mode 100644
index 1787aa3a3081b..0000000000000
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/utils.ts
+++ /dev/null
@@ -1,408 +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 { createHash } from 'crypto';
-import { performance } from 'perf_hooks';
-import { pickBy } from 'lodash/fp';
-import { SignalHit, Signal } from '../../types';
-import { Logger } from '../../../../../../../../src/core/server';
-import { AlertServices } from '../../../../../alerting/server/types';
-import {
- SignalSourceHit,
- SignalSearchResponse,
- BulkResponse,
- RuleTypeParams,
- OutputRuleAlertRest,
-} from './types';
-import { buildEventsSearchQuery } from './build_events_query';
-
-interface BuildRuleParams {
- ruleParams: RuleTypeParams;
- name: string;
- id: string;
- enabled: boolean;
- createdBy: string;
- updatedBy: string;
- interval: string;
- tags: string[];
-}
-
-export const buildRule = ({
- ruleParams,
- name,
- id,
- enabled,
- createdBy,
- updatedBy,
- interval,
- tags,
-}: BuildRuleParams): Partial => {
- return pickBy((value: unknown) => value != null, {
- id,
- rule_id: ruleParams.ruleId,
- false_positives: ruleParams.falsePositives,
- saved_id: ruleParams.savedId,
- meta: ruleParams.meta,
- max_signals: ruleParams.maxSignals,
- risk_score: ruleParams.riskScore,
- output_index: ruleParams.outputIndex,
- description: ruleParams.description,
- from: ruleParams.from,
- immutable: ruleParams.immutable,
- index: ruleParams.index,
- interval,
- language: ruleParams.language,
- name,
- query: ruleParams.query,
- references: ruleParams.references,
- severity: ruleParams.severity,
- tags,
- type: ruleParams.type,
- to: ruleParams.to,
- enabled,
- filters: ruleParams.filters,
- created_by: createdBy,
- updated_by: updatedBy,
- threats: ruleParams.threats,
- });
-};
-
-export const buildSignal = (doc: SignalSourceHit, rule: Partial): Signal => {
- const signal: Signal = {
- parent: {
- id: doc._id,
- type: 'event',
- index: doc._index,
- depth: 1,
- },
- original_time: doc._source['@timestamp'],
- status: 'open',
- rule,
- };
- if (doc._source.event != null) {
- return { ...signal, original_event: doc._source.event };
- }
- return signal;
-};
-
-interface BuildBulkBodyParams {
- doc: SignalSourceHit;
- ruleParams: RuleTypeParams;
- id: string;
- name: string;
- createdBy: string;
- updatedBy: string;
- interval: string;
- enabled: boolean;
- tags: string[];
-}
-
-export const buildEventTypeSignal = (doc: SignalSourceHit): object => {
- if (doc._source.event != null && doc._source.event instanceof Object) {
- return { ...doc._source.event, kind: 'signal' };
- } else {
- return { kind: 'signal' };
- }
-};
-
-// format search_after result for signals index.
-export const buildBulkBody = ({
- doc,
- ruleParams,
- id,
- name,
- createdBy,
- updatedBy,
- interval,
- enabled,
- tags,
-}: BuildBulkBodyParams): SignalHit => {
- const rule = buildRule({
- ruleParams,
- id,
- name,
- enabled,
- createdBy,
- updatedBy,
- interval,
- tags,
- });
- const signal = buildSignal(doc, rule);
- const event = buildEventTypeSignal(doc);
- const signalHit: SignalHit = {
- ...doc._source,
- '@timestamp': new Date().toISOString(),
- event,
- signal,
- };
- return signalHit;
-};
-
-interface SingleBulkCreateParams {
- someResult: SignalSearchResponse;
- ruleParams: RuleTypeParams;
- services: AlertServices;
- logger: Logger;
- id: string;
- signalsIndex: string;
- name: string;
- createdBy: string;
- updatedBy: string;
- interval: string;
- enabled: boolean;
- tags: string[];
-}
-
-export const generateId = (
- docIndex: string,
- docId: string,
- version: string,
- ruleId: string
-): string =>
- createHash('sha256')
- .update(docIndex.concat(docId, version, ruleId))
- .digest('hex');
-
-// Bulk Index documents.
-export const singleBulkCreate = async ({
- someResult,
- ruleParams,
- services,
- logger,
- id,
- signalsIndex,
- name,
- createdBy,
- updatedBy,
- interval,
- enabled,
- tags,
-}: SingleBulkCreateParams): Promise => {
- if (someResult.hits.hits.length === 0) {
- return true;
- }
- // index documents after creating an ID based on the
- // source documents' originating index, and the original
- // document _id. This will allow two documents from two
- // different indexes with the same ID to be
- // indexed, and prevents us from creating any updates
- // to the documents once inserted into the signals index,
- // while preventing duplicates from being added to the
- // signals index if rules are re-run over the same time
- // span. Also allow for versioning.
- const bulkBody = someResult.hits.hits.flatMap(doc => [
- {
- create: {
- _index: signalsIndex,
- _id: generateId(
- doc._index,
- doc._id,
- doc._version ? doc._version.toString() : '',
- ruleParams.ruleId ?? ''
- ),
- },
- },
- buildBulkBody({ doc, ruleParams, id, name, createdBy, updatedBy, interval, enabled, tags }),
- ]);
- const time1 = performance.now();
- const firstResult: BulkResponse = await services.callCluster('bulk', {
- index: signalsIndex,
- refresh: false,
- body: bulkBody,
- });
- const time2 = performance.now();
- logger.debug(
- `individual bulk process time took: ${Number(time2 - time1).toFixed(2)} milliseconds`
- );
- logger.debug(`took property says bulk took: ${firstResult.took} milliseconds`);
- if (firstResult.errors) {
- // go through the response status errors and see what
- // types of errors they are, count them up, and log them.
- const errorCountMap = firstResult.items.reduce((acc: { [key: string]: number }, item) => {
- if (item.create.error) {
- const responseStatusKey = item.create.status.toString();
- acc[responseStatusKey] = acc[responseStatusKey] ? acc[responseStatusKey] + 1 : 1;
- }
- return acc;
- }, {});
- /*
- the logging output below should look like
- {'409': 55}
- which is read as "there were 55 counts of 409 errors returned from bulk create"
- */
- logger.error(
- `[-] bulkResponse had errors with response statuses:counts of...\n${JSON.stringify(
- errorCountMap,
- null,
- 2
- )}`
- );
- }
- return true;
-};
-
-interface SingleSearchAfterParams {
- searchAfterSortId: string | undefined;
- ruleParams: RuleTypeParams;
- services: AlertServices;
- logger: Logger;
- pageSize: number;
- filter: unknown;
-}
-
-// utilize search_after for paging results into bulk.
-export const singleSearchAfter = async ({
- searchAfterSortId,
- ruleParams,
- services,
- filter,
- logger,
- pageSize,
-}: SingleSearchAfterParams): Promise => {
- if (searchAfterSortId == null) {
- throw Error('Attempted to search after with empty sort id');
- }
- try {
- const searchAfterQuery = buildEventsSearchQuery({
- index: ruleParams.index,
- from: ruleParams.from,
- to: ruleParams.to,
- filter,
- size: pageSize,
- searchAfterSortId,
- });
- const nextSearchAfterResult: SignalSearchResponse = await services.callCluster(
- 'search',
- searchAfterQuery
- );
- return nextSearchAfterResult;
- } catch (exc) {
- logger.error(`[-] nextSearchAfter threw an error ${exc}`);
- throw exc;
- }
-};
-
-interface SearchAfterAndBulkCreateParams {
- someResult: SignalSearchResponse;
- ruleParams: RuleTypeParams;
- services: AlertServices;
- logger: Logger;
- id: string;
- signalsIndex: string;
- name: string;
- createdBy: string;
- updatedBy: string;
- interval: string;
- enabled: boolean;
- pageSize: number;
- filter: unknown;
- tags: string[];
-}
-
-// search_after through documents and re-index using bulk endpoint.
-export const searchAfterAndBulkCreate = async ({
- someResult,
- ruleParams,
- services,
- logger,
- id,
- signalsIndex,
- filter,
- name,
- createdBy,
- updatedBy,
- interval,
- enabled,
- pageSize,
- tags,
-}: SearchAfterAndBulkCreateParams): Promise => {
- if (someResult.hits.hits.length === 0) {
- return true;
- }
-
- logger.debug('[+] starting bulk insertion');
- await singleBulkCreate({
- someResult,
- ruleParams,
- services,
- logger,
- id,
- signalsIndex,
- name,
- createdBy,
- updatedBy,
- interval,
- enabled,
- tags,
- });
- const totalHits =
- typeof someResult.hits.total === 'number' ? someResult.hits.total : someResult.hits.total.value;
- // maxTotalHitsSize represents the total number of docs to
- // query for, no matter the size of each individual page of search results.
- // If the total number of hits for the overall search result is greater than
- // maxSignals, default to requesting a total of maxSignals, otherwise use the
- // totalHits in the response from the searchAfter query.
- const maxTotalHitsSize = totalHits >= ruleParams.maxSignals ? ruleParams.maxSignals : totalHits;
-
- // number of docs in the current search result
- let hitsSize = someResult.hits.hits.length;
- logger.debug(`first size: ${hitsSize}`);
- let sortIds = someResult.hits.hits[0].sort;
- if (sortIds == null && totalHits > 0) {
- logger.error('sortIds was empty on first search but expected more');
- return false;
- } else if (sortIds == null && totalHits === 0) {
- return true;
- }
- let sortId;
- if (sortIds != null) {
- sortId = sortIds[0];
- }
- while (hitsSize < maxTotalHitsSize && hitsSize !== 0) {
- try {
- logger.debug(`sortIds: ${sortIds}`);
- const searchAfterResult: SignalSearchResponse = await singleSearchAfter({
- searchAfterSortId: sortId,
- ruleParams,
- services,
- logger,
- filter,
- pageSize, // maximum number of docs to receive per search result.
- });
- if (searchAfterResult.hits.hits.length === 0) {
- return true;
- }
- hitsSize += searchAfterResult.hits.hits.length;
- logger.debug(`size adjusted: ${hitsSize}`);
- sortIds = searchAfterResult.hits.hits[0].sort;
- if (sortIds == null) {
- logger.debug('sortIds was empty on search');
- return true; // no more search results
- }
- sortId = sortIds[0];
- logger.debug('next bulk index');
- await singleBulkCreate({
- someResult: searchAfterResult,
- ruleParams,
- services,
- logger,
- id,
- signalsIndex,
- name,
- createdBy,
- updatedBy,
- interval,
- enabled,
- tags,
- });
- logger.debug('finished next bulk index');
- } catch (exc) {
- logger.error(`[-] search_after and bulk threw an error ${exc}`);
- return false;
- }
- }
- logger.debug(`[+] completed bulk index of ${maxTotalHitsSize}`);
- return true;
-};
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts
index cd8b716221b9b..978434859ef95 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts
@@ -6,11 +6,13 @@
import { ServerInjectOptions } from 'hapi';
import { ActionResult } from '../../../../../../actions/server/types';
-import { RuleAlertParamsRest, RuleAlertType, SignalsRestParams } from '../../alerts/types';
+import { SignalsRestParams } from '../../signals/types';
import {
DETECTION_ENGINE_RULES_URL,
DETECTION_ENGINE_SIGNALS_STATUS_URL,
} from '../../../../../common/constants';
+import { RuleAlertType } from '../../rules/types';
+import { RuleAlertParamsRest } from '../../types';
// The Omit of filter is because of a Hapi Server Typing issue that I am unclear
// where it comes from. I would hope to remove the "filter" as an omit at some point
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/create_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.test.ts
similarity index 96%
rename from x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/create_rules_route.test.ts
rename to x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.test.ts
index b271af2db1e7d..094449a5f61ac 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/create_rules_route.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.test.ts
@@ -9,7 +9,7 @@ import {
createMockServerWithoutActionClientDecoration,
createMockServerWithoutAlertClientDecoration,
createMockServerWithoutActionOrAlertClientDecoration,
-} from './__mocks__/_mock_server';
+} from '../__mocks__/_mock_server';
import { createRulesRoute } from './create_rules_route';
import { ServerInjectOptions } from 'hapi';
import {
@@ -18,8 +18,8 @@ import {
createActionResult,
getCreateRequest,
typicalPayload,
-} from './__mocks__/request_responses';
-import { DETECTION_ENGINE_RULES_URL } from '../../../../common/constants';
+} from '../__mocks__/request_responses';
+import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
describe('create_rules', () => {
let { server, alertsClient, actionsClient, elasticsearch } = createMockServer();
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/create_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.ts
similarity index 85%
rename from x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/create_rules_route.ts
rename to x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.ts
index a137d54250189..0dc213e9e2173 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/create_rules_route.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.ts
@@ -8,14 +8,15 @@ import Hapi from 'hapi';
import { isFunction } from 'lodash/fp';
import Boom from 'boom';
import uuid from 'uuid';
-import { DETECTION_ENGINE_RULES_URL } from '../../../../common/constants';
-import { createRules } from '../alerts/create_rules';
-import { RulesRequest } from '../alerts/types';
-import { createRulesSchema } from './schemas';
-import { ServerFacade } from '../../../types';
-import { readRules } from '../alerts/read_rules';
-import { transformOrError, transformError, getIndex, callWithRequestFactory } from './utils';
-import { getIndexExists } from '../index/get_index_exists';
+import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
+import { createRules } from '../../rules/create_rules';
+import { RulesRequest } from '../../rules/types';
+import { createRulesSchema } from '../schemas/create_rules_schema';
+import { ServerFacade } from '../../../../types';
+import { readRules } from '../../rules/read_rules';
+import { transformOrError } from './utils';
+import { getIndexExists } from '../../index/get_index_exists';
+import { callWithRequestFactory, getIndex, transformError } from '../utils';
export const createCreateRulesRoute = (server: ServerFacade): Hapi.ServerRoute => {
return {
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/delete_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts
similarity index 96%
rename from x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/delete_rules_route.test.ts
rename to x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts
index 0808051964dc1..cacafcf741e6a 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/delete_rules_route.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts
@@ -9,7 +9,7 @@ import {
createMockServerWithoutActionClientDecoration,
createMockServerWithoutAlertClientDecoration,
createMockServerWithoutActionOrAlertClientDecoration,
-} from './__mocks__/_mock_server';
+} from '../__mocks__/_mock_server';
import { deleteRulesRoute } from './delete_rules_route';
import { ServerInjectOptions } from 'hapi';
@@ -19,8 +19,8 @@ import {
getDeleteRequest,
getFindResultWithSingleHit,
getDeleteRequestById,
-} from './__mocks__/request_responses';
-import { DETECTION_ENGINE_RULES_URL } from '../../../../common/constants';
+} from '../__mocks__/request_responses';
+import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
describe('delete_rules', () => {
let { server, alertsClient } = createMockServer();
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/delete_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_route.ts
similarity index 78%
rename from x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/delete_rules_route.ts
rename to x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_route.ts
index fe8b139f11c01..c2b2e2fdbbaef 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/delete_rules_route.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_route.ts
@@ -7,12 +7,13 @@
import Hapi from 'hapi';
import { isFunction } from 'lodash/fp';
-import { DETECTION_ENGINE_RULES_URL } from '../../../../common/constants';
-import { deleteRules } from '../alerts/delete_rules';
-import { ServerFacade } from '../../../types';
-import { queryRulesSchema } from './schemas';
-import { QueryRequest } from '../alerts/types';
-import { getIdError, transformOrError, transformError } from './utils';
+import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
+import { deleteRules } from '../../rules/delete_rules';
+import { ServerFacade } from '../../../../types';
+import { queryRulesSchema } from '../schemas/query_rules_schema';
+import { getIdError, transformOrError } from './utils';
+import { transformError } from '../utils';
+import { QueryRequest } from './types';
export const createDeleteRulesRoute: Hapi.ServerRoute = {
method: 'DELETE',
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/find_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_route.test.ts
similarity index 94%
rename from x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/find_rules_route.test.ts
rename to x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_route.test.ts
index dae40f05155dc..38937c13d302c 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/find_rules_route.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_route.test.ts
@@ -9,12 +9,12 @@ import {
createMockServerWithoutActionClientDecoration,
createMockServerWithoutAlertClientDecoration,
createMockServerWithoutActionOrAlertClientDecoration,
-} from './__mocks__/_mock_server';
+} from '../__mocks__/_mock_server';
import { findRulesRoute } from './find_rules_route';
import { ServerInjectOptions } from 'hapi';
-import { getFindResult, getResult, getFindRequest } from './__mocks__/request_responses';
-import { DETECTION_ENGINE_RULES_URL } from '../../../../common/constants';
+import { getFindResult, getResult, getFindRequest } from '../__mocks__/request_responses';
+import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
describe('find_rules', () => {
let { server, alertsClient, actionsClient } = createMockServer();
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/find_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_route.ts
similarity index 78%
rename from x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/find_rules_route.ts
rename to x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_route.ts
index 137dd9352699e..6e89ddb19017d 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/find_rules_route.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_route.ts
@@ -6,12 +6,13 @@
import Hapi from 'hapi';
import { isFunction } from 'lodash/fp';
-import { DETECTION_ENGINE_RULES_URL } from '../../../../common/constants';
-import { findRules } from '../alerts/find_rules';
-import { FindRulesRequest } from '../alerts/types';
-import { findRulesSchema } from './schemas';
-import { ServerFacade } from '../../../types';
-import { transformFindAlertsOrError, transformError } from './utils';
+import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
+import { findRules } from '../../rules/find_rules';
+import { FindRulesRequest } from '../../rules/types';
+import { findRulesSchema } from '../schemas/find_rules_schema';
+import { ServerFacade } from '../../../../types';
+import { transformFindAlertsOrError } from './utils';
+import { transformError } from '../utils';
export const createFindRulesRoute: Hapi.ServerRoute = {
method: 'GET',
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/read_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/read_rules_route.test.ts
similarity index 94%
rename from x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/read_rules_route.test.ts
rename to x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/read_rules_route.test.ts
index 47ecf62f41be9..0d77583573c13 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/read_rules_route.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/read_rules_route.test.ts
@@ -9,7 +9,7 @@ import {
createMockServerWithoutActionClientDecoration,
createMockServerWithoutAlertClientDecoration,
createMockServerWithoutActionOrAlertClientDecoration,
-} from './__mocks__/_mock_server';
+} from '../__mocks__/_mock_server';
import { readRulesRoute } from './read_rules_route';
import { ServerInjectOptions } from 'hapi';
@@ -18,8 +18,8 @@ import {
getResult,
getReadRequest,
getFindResultWithSingleHit,
-} from './__mocks__/request_responses';
-import { DETECTION_ENGINE_RULES_URL } from '../../../../common/constants';
+} from '../__mocks__/request_responses';
+import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
describe('read_signals', () => {
let { server, alertsClient } = createMockServer();
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/read_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/read_rules_route.ts
similarity index 78%
rename from x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/read_rules_route.ts
rename to x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/read_rules_route.ts
index a7bda40fdc523..a842e68b6b7fe 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/read_rules_route.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/read_rules_route.ts
@@ -6,13 +6,14 @@
import Hapi from 'hapi';
import { isFunction } from 'lodash/fp';
-import { DETECTION_ENGINE_RULES_URL } from '../../../../common/constants';
-import { getIdError, transformOrError, transformError } from './utils';
+import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
+import { getIdError, transformOrError } from './utils';
+import { transformError } from '../utils';
-import { readRules } from '../alerts/read_rules';
-import { ServerFacade } from '../../../types';
-import { queryRulesSchema } from './schemas';
-import { QueryRequest } from '../alerts/types';
+import { readRules } from '../../rules/read_rules';
+import { ServerFacade } from '../../../../types';
+import { queryRulesSchema } from '../schemas/query_rules_schema';
+import { QueryRequest } from './types';
export const createReadRulesRoute: Hapi.ServerRoute = {
method: 'GET',
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/types.ts
new file mode 100644
index 0000000000000..f6878c9edc9b8
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/types.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 { RequestFacade } from '../../../../types';
+
+export type QueryRequest = Omit & {
+ query: { id: string | undefined; rule_id: string | undefined };
+};
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/update_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.test.ts
similarity index 97%
rename from x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/update_rules_route.test.ts
rename to x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.test.ts
index dfa1275a6b26b..3cf5c07655d92 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/update_rules_route.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.test.ts
@@ -9,7 +9,7 @@ import {
createMockServerWithoutActionClientDecoration,
createMockServerWithoutAlertClientDecoration,
createMockServerWithoutActionOrAlertClientDecoration,
-} from './__mocks__/_mock_server';
+} from '../__mocks__/_mock_server';
import { updateRulesRoute } from './update_rules_route';
import { ServerInjectOptions } from 'hapi';
@@ -20,8 +20,8 @@ import {
getUpdateRequest,
typicalPayload,
getFindResultWithSingleHit,
-} from './__mocks__/request_responses';
-import { DETECTION_ENGINE_RULES_URL } from '../../../../common/constants';
+} from '../__mocks__/request_responses';
+import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
describe('update_rules', () => {
let { server, alertsClient, actionsClient } = createMockServer();
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/update_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.ts
similarity index 84%
rename from x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/update_rules_route.ts
rename to x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.ts
index 943c41fd6dea6..2e7b48afbb5d9 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/update_rules_route.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.ts
@@ -6,12 +6,13 @@
import Hapi from 'hapi';
import { isFunction } from 'lodash/fp';
-import { DETECTION_ENGINE_RULES_URL } from '../../../../common/constants';
-import { updateRules } from '../alerts/update_rules';
-import { UpdateRulesRequest } from '../alerts/types';
-import { updateRulesSchema } from './schemas';
-import { ServerFacade } from '../../../types';
-import { getIdError, transformOrError, transformError } from './utils';
+import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
+import { updateRules } from '../../rules/update_rules';
+import { UpdateRulesRequest } from '../../rules/types';
+import { updateRulesSchema } from '../schemas/update_rules_schema';
+import { ServerFacade } from '../../../../types';
+import { getIdError, transformOrError } from './utils';
+import { transformError } from '../utils';
export const createUpdateRulesRoute: Hapi.ServerRoute = {
method: 'PUT',
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.test.ts
new file mode 100644
index 0000000000000..d4e129f543ccf
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.test.ts
@@ -0,0 +1,496 @@
+/*
+ * 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 Boom from 'boom';
+
+import {
+ transformAlertToRule,
+ getIdError,
+ transformFindAlertsOrError,
+ transformOrError,
+} from './utils';
+import { getResult } from '../__mocks__/request_responses';
+
+describe('utils', () => {
+ describe('transformAlertToRule', () => {
+ test('should work with a full data set', () => {
+ const fullRule = getResult();
+ const rule = transformAlertToRule(fullRule);
+ expect(rule).toEqual({
+ created_by: 'elastic',
+ description: 'Detecting root and admin users',
+ enabled: true,
+ false_positives: [],
+ from: 'now-6m',
+ id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
+ immutable: false,
+ index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
+ interval: '5m',
+ risk_score: 50,
+ rule_id: 'rule-1',
+ language: 'kuery',
+ max_signals: 100,
+ name: 'Detect Root/Admin Users',
+ output_index: '.siem-signals',
+ query: 'user.name: root or user.name: admin',
+ references: ['http://www.example.com', 'https://ww.example.com'],
+ severity: 'high',
+ updated_by: 'elastic',
+ tags: [],
+ threats: [
+ {
+ framework: 'MITRE ATT&CK',
+ tactic: {
+ id: 'TA0040',
+ name: 'impact',
+ reference: 'https://attack.mitre.org/tactics/TA0040/',
+ },
+ techniques: [
+ {
+ id: 'T1499',
+ name: 'endpoint denial of service',
+ reference: 'https://attack.mitre.org/techniques/T1499/',
+ },
+ ],
+ },
+ ],
+ to: 'now',
+ type: 'query',
+ });
+ });
+
+ test('should work with a partial data set missing data', () => {
+ const fullRule = getResult();
+ const { from, language, ...omitData } = transformAlertToRule(fullRule);
+ expect(omitData).toEqual({
+ created_by: 'elastic',
+ description: 'Detecting root and admin users',
+ enabled: true,
+ false_positives: [],
+ id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
+ immutable: false,
+ index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
+ output_index: '.siem-signals',
+ interval: '5m',
+ risk_score: 50,
+ rule_id: 'rule-1',
+ max_signals: 100,
+ name: 'Detect Root/Admin Users',
+ query: 'user.name: root or user.name: admin',
+ references: ['http://www.example.com', 'https://ww.example.com'],
+ severity: 'high',
+ updated_by: 'elastic',
+ tags: [],
+ threats: [
+ {
+ framework: 'MITRE ATT&CK',
+ tactic: {
+ id: 'TA0040',
+ name: 'impact',
+ reference: 'https://attack.mitre.org/tactics/TA0040/',
+ },
+ techniques: [
+ {
+ id: 'T1499',
+ name: 'endpoint denial of service',
+ reference: 'https://attack.mitre.org/techniques/T1499/',
+ },
+ ],
+ },
+ ],
+ to: 'now',
+ type: 'query',
+ });
+ });
+
+ test('should omit query if query is null', () => {
+ const fullRule = getResult();
+ fullRule.params.query = null;
+ const rule = transformAlertToRule(fullRule);
+ expect(rule).toEqual({
+ created_by: 'elastic',
+ description: 'Detecting root and admin users',
+ enabled: true,
+ false_positives: [],
+ from: 'now-6m',
+ id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
+ immutable: false,
+ index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
+ output_index: '.siem-signals',
+ interval: '5m',
+ risk_score: 50,
+ rule_id: 'rule-1',
+ language: 'kuery',
+ max_signals: 100,
+ name: 'Detect Root/Admin Users',
+ references: ['http://www.example.com', 'https://ww.example.com'],
+ severity: 'high',
+ updated_by: 'elastic',
+ tags: [],
+ threats: [
+ {
+ framework: 'MITRE ATT&CK',
+ tactic: {
+ id: 'TA0040',
+ name: 'impact',
+ reference: 'https://attack.mitre.org/tactics/TA0040/',
+ },
+ techniques: [
+ {
+ id: 'T1499',
+ name: 'endpoint denial of service',
+ reference: 'https://attack.mitre.org/techniques/T1499/',
+ },
+ ],
+ },
+ ],
+ to: 'now',
+ type: 'query',
+ });
+ });
+
+ test('should omit query if query is undefined', () => {
+ const fullRule = getResult();
+ fullRule.params.query = undefined;
+ const rule = transformAlertToRule(fullRule);
+ expect(rule).toEqual({
+ created_by: 'elastic',
+ description: 'Detecting root and admin users',
+ enabled: true,
+ false_positives: [],
+ from: 'now-6m',
+ id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
+ immutable: false,
+ index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
+ output_index: '.siem-signals',
+ interval: '5m',
+ rule_id: 'rule-1',
+ risk_score: 50,
+ language: 'kuery',
+ max_signals: 100,
+ name: 'Detect Root/Admin Users',
+ references: ['http://www.example.com', 'https://ww.example.com'],
+ severity: 'high',
+ updated_by: 'elastic',
+ tags: [],
+ threats: [
+ {
+ framework: 'MITRE ATT&CK',
+ tactic: {
+ id: 'TA0040',
+ name: 'impact',
+ reference: 'https://attack.mitre.org/tactics/TA0040/',
+ },
+ techniques: [
+ {
+ id: 'T1499',
+ name: 'endpoint denial of service',
+ reference: 'https://attack.mitre.org/techniques/T1499/',
+ },
+ ],
+ },
+ ],
+ to: 'now',
+ type: 'query',
+ });
+ });
+
+ test('should omit a mix of undefined, null, and missing fields', () => {
+ const fullRule = getResult();
+ fullRule.params.query = undefined;
+ fullRule.params.language = null;
+ const { from, enabled, ...omitData } = transformAlertToRule(fullRule);
+ expect(omitData).toEqual({
+ created_by: 'elastic',
+ description: 'Detecting root and admin users',
+ false_positives: [],
+ id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
+ immutable: false,
+ output_index: '.siem-signals',
+ index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
+ interval: '5m',
+ rule_id: 'rule-1',
+ risk_score: 50,
+ max_signals: 100,
+ name: 'Detect Root/Admin Users',
+ references: ['http://www.example.com', 'https://ww.example.com'],
+ severity: 'high',
+ updated_by: 'elastic',
+ tags: [],
+ threats: [
+ {
+ framework: 'MITRE ATT&CK',
+ tactic: {
+ id: 'TA0040',
+ name: 'impact',
+ reference: 'https://attack.mitre.org/tactics/TA0040/',
+ },
+ techniques: [
+ {
+ id: 'T1499',
+ name: 'endpoint denial of service',
+ reference: 'https://attack.mitre.org/techniques/T1499/',
+ },
+ ],
+ },
+ ],
+ to: 'now',
+ type: 'query',
+ });
+ });
+
+ test('should return enabled is equal to false', () => {
+ const fullRule = getResult();
+ fullRule.enabled = false;
+ const ruleWithEnabledFalse = transformAlertToRule(fullRule);
+ expect(ruleWithEnabledFalse).toEqual({
+ created_by: 'elastic',
+ description: 'Detecting root and admin users',
+ enabled: false,
+ from: 'now-6m',
+ false_positives: [],
+ id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
+ immutable: false,
+ output_index: '.siem-signals',
+ index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
+ interval: '5m',
+ language: 'kuery',
+ risk_score: 50,
+ rule_id: 'rule-1',
+ max_signals: 100,
+ name: 'Detect Root/Admin Users',
+ query: 'user.name: root or user.name: admin',
+ references: ['http://www.example.com', 'https://ww.example.com'],
+ severity: 'high',
+ updated_by: 'elastic',
+ tags: [],
+ threats: [
+ {
+ framework: 'MITRE ATT&CK',
+ tactic: {
+ id: 'TA0040',
+ name: 'impact',
+ reference: 'https://attack.mitre.org/tactics/TA0040/',
+ },
+ techniques: [
+ {
+ id: 'T1499',
+ name: 'endpoint denial of service',
+ reference: 'https://attack.mitre.org/techniques/T1499/',
+ },
+ ],
+ },
+ ],
+ to: 'now',
+ type: 'query',
+ });
+ });
+
+ test('should return immutable is equal to false', () => {
+ const fullRule = getResult();
+ fullRule.params.immutable = false;
+ const ruleWithEnabledFalse = transformAlertToRule(fullRule);
+ expect(ruleWithEnabledFalse).toEqual({
+ created_by: 'elastic',
+ description: 'Detecting root and admin users',
+ enabled: true,
+ from: 'now-6m',
+ false_positives: [],
+ id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
+ immutable: false,
+ output_index: '.siem-signals',
+ index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
+ interval: '5m',
+ language: 'kuery',
+ risk_score: 50,
+ rule_id: 'rule-1',
+ max_signals: 100,
+ name: 'Detect Root/Admin Users',
+ query: 'user.name: root or user.name: admin',
+ references: ['http://www.example.com', 'https://ww.example.com'],
+ severity: 'high',
+ updated_by: 'elastic',
+ tags: [],
+ threats: [
+ {
+ framework: 'MITRE ATT&CK',
+ tactic: {
+ id: 'TA0040',
+ name: 'impact',
+ reference: 'https://attack.mitre.org/tactics/TA0040/',
+ },
+ techniques: [
+ {
+ id: 'T1499',
+ name: 'endpoint denial of service',
+ reference: 'https://attack.mitre.org/techniques/T1499/',
+ },
+ ],
+ },
+ ],
+ to: 'now',
+ type: 'query',
+ });
+ });
+ });
+
+ describe('getIdError', () => {
+ test('outputs message about id not being found if only id is defined and ruleId is undefined', () => {
+ const boom = getIdError({ id: '123', ruleId: undefined });
+ expect(boom.message).toEqual('id: "123" not found');
+ });
+
+ test('outputs message about id not being found if only id is defined and ruleId is null', () => {
+ const boom = getIdError({ id: '123', ruleId: null });
+ expect(boom.message).toEqual('id: "123" not found');
+ });
+
+ test('outputs message about ruleId not being found if only ruleId is defined and id is undefined', () => {
+ const boom = getIdError({ id: undefined, ruleId: 'rule-id-123' });
+ expect(boom.message).toEqual('rule_id: "rule-id-123" not found');
+ });
+
+ test('outputs message about ruleId not being found if only ruleId is defined and id is null', () => {
+ const boom = getIdError({ id: null, ruleId: 'rule-id-123' });
+ expect(boom.message).toEqual('rule_id: "rule-id-123" not found');
+ });
+
+ test('outputs message about both being not defined when both are undefined', () => {
+ const boom = getIdError({ id: undefined, ruleId: undefined });
+ expect(boom.message).toEqual('id or rule_id should have been defined');
+ });
+
+ test('outputs message about both being not defined when both are null', () => {
+ const boom = getIdError({ id: null, ruleId: null });
+ expect(boom.message).toEqual('id or rule_id should have been defined');
+ });
+
+ test('outputs message about both being not defined when id is null and ruleId is undefined', () => {
+ const boom = getIdError({ id: null, ruleId: undefined });
+ expect(boom.message).toEqual('id or rule_id should have been defined');
+ });
+
+ test('outputs message about both being not defined when id is undefined and ruleId is null', () => {
+ const boom = getIdError({ id: undefined, ruleId: null });
+ expect(boom.message).toEqual('id or rule_id should have been defined');
+ });
+ });
+
+ describe('transformFindAlertsOrError', () => {
+ test('outputs empty data set when data set is empty correct', () => {
+ const output = transformFindAlertsOrError({ data: [] });
+ expect(output).toEqual({ data: [] });
+ });
+
+ test('outputs 200 if the data is of type siem alert', () => {
+ const output = transformFindAlertsOrError({
+ data: [getResult()],
+ });
+ expect(output).toEqual({
+ data: [
+ {
+ created_by: 'elastic',
+ description: 'Detecting root and admin users',
+ enabled: true,
+ false_positives: [],
+ from: 'now-6m',
+ id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
+ immutable: false,
+ output_index: '.siem-signals',
+ index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
+ interval: '5m',
+ risk_score: 50,
+ rule_id: 'rule-1',
+ language: 'kuery',
+ max_signals: 100,
+ name: 'Detect Root/Admin Users',
+ query: 'user.name: root or user.name: admin',
+ references: ['http://www.example.com', 'https://ww.example.com'],
+ severity: 'high',
+ updated_by: 'elastic',
+ tags: [],
+ to: 'now',
+ type: 'query',
+ threats: [
+ {
+ framework: 'MITRE ATT&CK',
+ tactic: {
+ id: 'TA0040',
+ name: 'impact',
+ reference: 'https://attack.mitre.org/tactics/TA0040/',
+ },
+ techniques: [
+ {
+ id: 'T1499',
+ name: 'endpoint denial of service',
+ reference: 'https://attack.mitre.org/techniques/T1499/',
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ });
+ });
+
+ test('returns 500 if the data is not of type siem alert', () => {
+ const output = transformFindAlertsOrError({ data: [{ random: 1 }] });
+ expect((output as Boom).message).toEqual('Internal error transforming');
+ });
+ });
+
+ describe('transformOrError', () => {
+ test('outputs 200 if the data is of type siem alert', () => {
+ const output = transformOrError(getResult());
+ expect(output).toEqual({
+ created_by: 'elastic',
+ description: 'Detecting root and admin users',
+ enabled: true,
+ false_positives: [],
+ from: 'now-6m',
+ id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
+ immutable: false,
+ output_index: '.siem-signals',
+ index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
+ interval: '5m',
+ rule_id: 'rule-1',
+ risk_score: 50,
+ language: 'kuery',
+ max_signals: 100,
+ name: 'Detect Root/Admin Users',
+ query: 'user.name: root or user.name: admin',
+ references: ['http://www.example.com', 'https://ww.example.com'],
+ severity: 'high',
+ updated_by: 'elastic',
+ tags: [],
+ to: 'now',
+ type: 'query',
+ threats: [
+ {
+ framework: 'MITRE ATT&CK',
+ tactic: {
+ id: 'TA0040',
+ name: 'impact',
+ reference: 'https://attack.mitre.org/tactics/TA0040/',
+ },
+ techniques: [
+ {
+ id: 'T1499',
+ name: 'endpoint denial of service',
+ reference: 'https://attack.mitre.org/techniques/T1499/',
+ },
+ ],
+ },
+ ],
+ });
+ });
+
+ test('returns 500 if the data is not of type siem alert', () => {
+ const output = transformOrError({ data: [{ random: 1 }] });
+ expect((output as Boom).message).toEqual('Internal error transforming');
+ });
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.ts
new file mode 100644
index 0000000000000..c9ae3abdfdc6b
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.ts
@@ -0,0 +1,76 @@
+/*
+ * 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 Boom from 'boom';
+import { pickBy } from 'lodash/fp';
+import { RuleAlertType, isAlertType, isAlertTypes } from '../../rules/types';
+import { OutputRuleAlertRest } from '../../types';
+
+export const getIdError = ({
+ id,
+ ruleId,
+}: {
+ id: string | undefined | null;
+ ruleId: string | undefined | null;
+}) => {
+ if (id != null) {
+ return new Boom(`id: "${id}" not found`, { statusCode: 404 });
+ } else if (ruleId != null) {
+ return new Boom(`rule_id: "${ruleId}" not found`, { statusCode: 404 });
+ } else {
+ return new Boom(`id or rule_id should have been defined`, { statusCode: 404 });
+ }
+};
+
+// Transforms the data but will remove any null or undefined it encounters and not include
+// those on the export
+export const transformAlertToRule = (alert: RuleAlertType): Partial => {
+ return pickBy((value: unknown) => value != null, {
+ created_by: alert.createdBy,
+ description: alert.params.description,
+ enabled: alert.enabled,
+ false_positives: alert.params.falsePositives,
+ filters: alert.params.filters,
+ from: alert.params.from,
+ id: alert.id,
+ immutable: alert.params.immutable,
+ index: alert.params.index,
+ interval: alert.interval,
+ rule_id: alert.params.ruleId,
+ language: alert.params.language,
+ output_index: alert.params.outputIndex,
+ max_signals: alert.params.maxSignals,
+ risk_score: alert.params.riskScore,
+ name: alert.name,
+ query: alert.params.query,
+ references: alert.params.references,
+ saved_id: alert.params.savedId,
+ meta: alert.params.meta,
+ severity: alert.params.severity,
+ updated_by: alert.updatedBy,
+ tags: alert.tags,
+ to: alert.params.to,
+ type: alert.params.type,
+ threats: alert.params.threats,
+ });
+};
+
+export const transformFindAlertsOrError = (findResults: { data: unknown[] }): unknown | Boom => {
+ if (isAlertTypes(findResults.data)) {
+ findResults.data = findResults.data.map(alert => transformAlertToRule(alert));
+ return findResults;
+ } else {
+ return new Boom('Internal error transforming', { statusCode: 500 });
+ }
+};
+
+export const transformOrError = (alert: unknown): Partial | Boom => {
+ if (isAlertType(alert)) {
+ return transformAlertToRule(alert);
+ } else {
+ return new Boom('Internal error transforming', { statusCode: 500 });
+ }
+};
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.test.ts
deleted file mode 100644
index f5147bc5a8f8b..0000000000000
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.test.ts
+++ /dev/null
@@ -1,2133 +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 {
- createRulesSchema,
- updateRulesSchema,
- findRulesSchema,
- queryRulesSchema,
- setSignalsStatusSchema,
-} from './schemas';
-import {
- RuleAlertParamsRest,
- FindParamsRest,
- UpdateRuleAlertParamsRest,
- ThreatParams,
- SignalsRestParams,
-} from '../alerts/types';
-
-describe('schemas', () => {
- describe('create rules schema', () => {
- test('empty objects do not validate', () => {
- expect(createRulesSchema.validate>({}).error).toBeTruthy();
- });
-
- test('made up values do not validate', () => {
- expect(
- createRulesSchema.validate>({
- madeUp: 'hi',
- }).error
- ).toBeTruthy();
- });
-
- test('[rule_id] does not validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- }).error
- ).toBeTruthy();
- });
-
- test('[rule_id, description] does not validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- }).error
- ).toBeTruthy();
- });
-
- test('[rule_id, description, from] does not validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- }).error
- ).toBeTruthy();
- });
-
- test('[rule_id, description, from, to] does not validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- }).error
- ).toBeTruthy();
- });
-
- test('[rule_id, description, from, to, name] does not validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- name: 'some-name',
- }).error
- ).toBeTruthy();
- });
-
- test('[rule_id, description, from, to, name, severity] does not validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- name: 'some-name',
- severity: 'severity',
- }).error
- ).toBeTruthy();
- });
-
- test('[rule_id, description, from, to, name, severity, type] does not validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- name: 'some-name',
- severity: 'severity',
- type: 'query',
- }).error
- ).toBeTruthy();
- });
-
- test('[rule_id, description, from, to, name, severity, type, interval] does not validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- }).error
- ).toBeTruthy();
- });
-
- test('[rule_id, description, from, to, name, severity, type, interval, index] does not validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- name: 'some-name',
- severity: 'severity',
- type: 'query',
- interval: '5m',
- index: ['index-1'],
- }).error
- ).toBeTruthy();
- });
-
- test('[rule_id, description, from, to, name, severity, type, query, index, interval] does validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- name: 'some-name',
- severity: 'severity',
- type: 'query',
- query: 'some query',
- index: ['index-1'],
- interval: '5m',
- }).error
- ).toBeFalsy();
- });
-
- test('[rule_id, description, from, to, index, name, severity, interval, type, query, language] does not validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- query: 'some query',
- language: 'kuery',
- }).error
- ).toBeTruthy();
- });
-
- test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score] does validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- query: 'some query',
- language: 'kuery',
- }).error
- ).toBeFalsy();
- });
-
- test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score, output_index] does validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- query: 'some query',
- language: 'kuery',
- }).error
- ).toBeFalsy();
- });
-
- test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score] does validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- risk_score: 50,
- }).error
- ).toBeFalsy();
- });
-
- test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index] does validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- }).error
- ).toBeFalsy();
- });
- test('You can send in an empty array to threats', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- threats: [],
- }).error
- ).toBeFalsy();
- });
- test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index, threats] does validate', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- threats: [
- {
- framework: 'someFramework',
- tactic: {
- id: 'fakeId',
- name: 'fakeName',
- reference: 'fakeRef',
- },
- techniques: [
- {
- id: 'techniqueId',
- name: 'techniqueName',
- reference: 'techniqueRef',
- },
- ],
- },
- ],
- }).error
- ).toBeFalsy();
- });
-
- test('allows references to be sent as valid', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- }).error
- ).toBeFalsy();
- });
-
- test('defaults references to an array', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- query: 'some-query',
- language: 'kuery',
- }).value.references
- ).toEqual([]);
- });
-
- test('references cannot be numbers', () => {
- expect(
- createRulesSchema.validate<
- Partial> & { references: number[] }
- >({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- query: 'some-query',
- language: 'kuery',
- references: [5],
- }).error
- ).toBeTruthy();
- });
-
- test('indexes cannot be numbers', () => {
- expect(
- createRulesSchema.validate<
- Partial> & { index: number[] }
- >({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: [5],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- query: 'some-query',
- language: 'kuery',
- }).error
- ).toBeTruthy();
- });
-
- test('defaults interval to 5 min', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- type: 'query',
- }).value.interval
- ).toEqual('5m');
- });
-
- test('defaults max signals to 100', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- }).value.max_signals
- ).toEqual(100);
- });
-
- test('saved_id is required when type is saved_query and will not validate without out', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'saved_query',
- }).error
- ).toBeTruthy();
- });
-
- test('saved_id is required when type is saved_query and validates with it', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- risk_score: 50,
- output_index: '.siem-signals',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'saved_query',
- saved_id: 'some id',
- }).error
- ).toBeFalsy();
- });
-
- test('saved_query type can have filters with it', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'saved_query',
- saved_id: 'some id',
- filters: [],
- }).error
- ).toBeFalsy();
- });
-
- test('filters cannot be a string', () => {
- expect(
- createRulesSchema.validate<
- Partial & { filters: string }>
- >({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'saved_query',
- saved_id: 'some id',
- filters: 'some string',
- }).error
- ).toBeTruthy();
- });
-
- test('language validates with kuery', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- }).error
- ).toBeFalsy();
- });
-
- test('language validates with lucene', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- risk_score: 50,
- output_index: '.siem-signals',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'lucene',
- }).error
- ).toBeFalsy();
- });
-
- test('language does not validate with something made up', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'something-made-up',
- }).error
- ).toBeTruthy();
- });
-
- test('max_signals cannot be negative', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: -1,
- }).error
- ).toBeTruthy();
- });
-
- test('max_signals cannot be zero', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 0,
- }).error
- ).toBeTruthy();
- });
-
- test('max_signals can be 1', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- }).error
- ).toBeFalsy();
- });
-
- test('You can optionally send in an array of tags', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- tags: ['tag_1', 'tag_2'],
- }).error
- ).toBeFalsy();
- });
-
- test('You cannot send in an array of tags that are numbers', () => {
- expect(
- createRulesSchema.validate> & { tags: number[] }>(
- {
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- tags: [0, 1, 2],
- }
- ).error
- ).toBeTruthy();
- });
-
- test('You cannot send in an array of threats that are missing "framework"', () => {
- expect(
- createRulesSchema.validate<
- Partial> & {
- threats: Array>>;
- }
- >({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- threats: [
- {
- tactic: {
- id: 'fakeId',
- name: 'fakeName',
- reference: 'fakeRef',
- },
- techniques: [
- {
- id: 'techniqueId',
- name: 'techniqueName',
- reference: 'techniqueRef',
- },
- ],
- },
- ],
- }).error
- ).toBeTruthy();
- });
- test('You cannot send in an array of threats that are missing "tactic"', () => {
- expect(
- createRulesSchema.validate<
- Partial> & {
- threats: Array>>;
- }
- >({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- threats: [
- {
- framework: 'fake',
- techniques: [
- {
- id: 'techniqueId',
- name: 'techniqueName',
- reference: 'techniqueRef',
- },
- ],
- },
- ],
- }).error
- ).toBeTruthy();
- });
- test('You cannot send in an array of threats that are missing "techniques"', () => {
- expect(
- createRulesSchema.validate<
- Partial> & {
- threats: Array>>;
- }
- >({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- threats: [
- {
- framework: 'fake',
- tactic: {
- id: 'fakeId',
- name: 'fakeName',
- reference: 'fakeRef',
- },
- },
- ],
- }).error
- ).toBeTruthy();
- });
-
- test('You can optionally send in an array of false positives', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- false_positives: ['false_1', 'false_2'],
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- }).error
- ).toBeFalsy();
- });
-
- test('You cannot send in an array of false positives that are numbers', () => {
- expect(
- createRulesSchema.validate<
- Partial> & { false_positives: number[] }
- >({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- false_positives: [5, 4],
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- }).error
- ).toBeTruthy();
- });
-
- test('You can optionally set the immutable to be true', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- immutable: true,
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- }).error
- ).toBeFalsy();
- });
-
- test('You cannot set the immutable to be a number', () => {
- expect(
- createRulesSchema.validate<
- Partial> & { immutable: number }
- >({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- immutable: 5,
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- }).error
- ).toBeTruthy();
- });
-
- test('You cannot set the risk_score to 101', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 101,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- immutable: true,
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- }).error
- ).toBeTruthy();
- });
-
- test('You cannot set the risk_score to -1', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: -1,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- immutable: true,
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- }).error
- ).toBeTruthy();
- });
-
- test('You can set the risk_score to 0', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 0,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- immutable: true,
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- }).error
- ).toBeFalsy();
- });
-
- test('You can set the risk_score to 100', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 100,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- immutable: true,
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- }).error
- ).toBeFalsy();
- });
-
- test('You can set meta to any object you want', () => {
- expect(
- createRulesSchema.validate>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- immutable: true,
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- meta: {
- somethingMadeUp: { somethingElse: true },
- },
- }).error
- ).toBeFalsy();
- });
-
- test('You cannot create meta as a string', () => {
- expect(
- createRulesSchema.validate & { meta: string }>>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- immutable: true,
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- meta: 'should not work',
- }).error
- ).toBeTruthy();
- });
-
- test('You can omit the query string when filters are present', () => {
- expect(
- createRulesSchema.validate & { meta: string }>>({
- rule_id: 'rule-1',
- output_index: '.siem-signals',
- risk_score: 50,
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- immutable: true,
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- language: 'kuery',
- filters: [],
- max_signals: 1,
- }).error
- ).toBeFalsy();
- });
- });
-
- describe('update rules schema', () => {
- test('empty objects do not validate as they require at least id or rule_id', () => {
- expect(updateRulesSchema.validate>({}).error).toBeTruthy();
- });
-
- test('made up values do not validate', () => {
- expect(
- updateRulesSchema.validate>({
- madeUp: 'hi',
- }).error
- ).toBeTruthy();
- });
-
- test('[id] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- }).error
- ).toBeFalsy();
- });
-
- test('[rule_id] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- rule_id: 'rule-1',
- }).error
- ).toBeFalsy();
- });
-
- test('[id and rule_id] does not validate', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'id-1',
- rule_id: 'rule-1',
- }).error
- ).toBeTruthy();
- });
-
- test('[rule_id, description] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- }).error
- ).toBeFalsy();
- });
-
- test('[id, description] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- }).error
- ).toBeFalsy();
- });
-
- test('[id, risk_score] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- risk_score: 10,
- }).error
- ).toBeFalsy();
- });
-
- test('[rule_id, description, from] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- }).error
- ).toBeFalsy();
- });
-
- test('[id, description, from] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- }).error
- ).toBeFalsy();
- });
-
- test('[rule_id, description, from, to] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- }).error
- ).toBeFalsy();
- });
-
- test('[id, description, from, to] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- }).error
- ).toBeFalsy();
- });
-
- test('[rule_id, description, from, to, name] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- name: 'some-name',
- }).error
- ).toBeFalsy();
- });
-
- test('[id, description, from, to, name] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- name: 'some-name',
- }).error
- ).toBeFalsy();
- });
-
- test('[rule_id, description, from, to, name, severity] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- name: 'some-name',
- severity: 'severity',
- }).error
- ).toBeFalsy();
- });
-
- test('[id, description, from, to, name, severity] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- name: 'some-name',
- severity: 'severity',
- }).error
- ).toBeFalsy();
- });
-
- test('[rule_id, description, from, to, name, severity, type] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- name: 'some-name',
- severity: 'severity',
- type: 'query',
- }).error
- ).toBeFalsy();
- });
-
- test('[id, description, from, to, name, severity, type] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- name: 'some-name',
- severity: 'severity',
- type: 'query',
- }).error
- ).toBeFalsy();
- });
-
- test('[rule_id, description, from, to, name, severity, type, interval] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- }).error
- ).toBeFalsy();
- });
-
- test('[id, description, from, to, name, severity, type, interval] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- }).error
- ).toBeFalsy();
- });
-
- test('[rule_id, description, from, to, index, name, severity, interval, type] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- }).error
- ).toBeFalsy();
- });
-
- test('[id, description, from, to, index, name, severity, interval, type] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- }).error
- ).toBeFalsy();
- });
-
- test('[rule_id, description, from, to, index, name, severity, interval, type, query] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- query: 'some query',
- }).error
- ).toBeFalsy();
- });
-
- test('[id, description, from, to, index, name, severity, interval, type, query] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- query: 'some query',
- }).error
- ).toBeFalsy();
- });
-
- test('[rule_id, description, from, to, index, name, severity, interval, type, query, language] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- query: 'some query',
- language: 'kuery',
- }).error
- ).toBeFalsy();
- });
-
- test('[id, description, from, to, index, name, severity, interval, type, query, language] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- query: 'some query',
- language: 'kuery',
- }).error
- ).toBeFalsy();
- });
-
- test('[rule_id, description, from, to, index, name, severity, type, filter] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- rule_id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- }).error
- ).toBeFalsy();
- });
-
- test('[id, description, from, to, index, name, severity, type, filter] does validate', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- }).error
- ).toBeFalsy();
- });
-
- test('allows references to be sent as a valid value to update with', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- }).error
- ).toBeFalsy();
- });
-
- test('does not default references to an array', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- query: 'some-query',
- language: 'kuery',
- }).value.references
- ).toEqual(undefined);
- });
-
- test('does not default interval', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- type: 'query',
- }).value.interval
- ).toEqual(undefined);
- });
-
- test('does not default max signal', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- }).value.max_signals
- ).toEqual(undefined);
- });
-
- test('references cannot be numbers', () => {
- expect(
- updateRulesSchema.validate<
- Partial> & { references: number[] }
- >({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- query: 'some-query',
- language: 'kuery',
- references: [5],
- }).error
- ).toBeTruthy();
- });
-
- test('indexes cannot be numbers', () => {
- expect(
- updateRulesSchema.validate<
- Partial> & { index: number[] }
- >({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: [5],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- query: 'some-query',
- language: 'kuery',
- }).error
- ).toBeTruthy();
- });
-
- test('saved_id is not required when type is saved_query and will validate without it', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'saved_query',
- }).error
- ).toBeFalsy();
- });
-
- test('saved_id validates with saved_query', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'saved_query',
- saved_id: 'some id',
- }).error
- ).toBeFalsy();
- });
-
- test('saved_query type can have filters with it', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'saved_query',
- saved_id: 'some id',
- filters: [],
- }).error
- ).toBeFalsy();
- });
-
- test('language validates with kuery', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- }).error
- ).toBeFalsy();
- });
-
- test('language validates with lucene', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'lucene',
- }).error
- ).toBeFalsy();
- });
-
- test('language does not validate with something made up', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'something-made-up',
- }).error
- ).toBeTruthy();
- });
-
- test('max_signals cannot be negative', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: -1,
- }).error
- ).toBeTruthy();
- });
-
- test('max_signals cannot be zero', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 0,
- }).error
- ).toBeTruthy();
- });
-
- test('max_signals can be 1', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- }).error
- ).toBeFalsy();
- });
-
- test('meta can be updated', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- meta: { whateverYouWant: 'anything_at_all' },
- }).error
- ).toBeFalsy();
- });
-
- test('You update meta as a string', () => {
- expect(
- updateRulesSchema.validate<
- Partial & { meta: string }>
- >({
- id: 'rule-1',
- meta: 'should not work',
- }).error
- ).toBeTruthy();
- });
-
- test('filters cannot be a string', () => {
- expect(
- updateRulesSchema.validate<
- Partial & { filters: string }>
- >({
- rule_id: 'rule-1',
- type: 'query',
- filters: 'some string',
- }).error
- ).toBeTruthy();
- });
-
- test('threats is not defaulted to empty array on update', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- }).value.threats
- ).toBe(undefined);
- });
-
- test('threats is not defaulted to undefined on update with empty array', () => {
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- threats: [],
- }).value.threats
- ).toMatchObject([]);
- });
- test('threats is valid when updated with all sub-objects', () => {
- const expected: ThreatParams[] = [
- {
- framework: 'fake',
- tactic: {
- id: 'fakeId',
- name: 'fakeName',
- reference: 'fakeRef',
- },
- techniques: [
- {
- id: 'techniqueId',
- name: 'techniqueName',
- reference: 'techniqueRef',
- },
- ],
- },
- ];
- expect(
- updateRulesSchema.validate>({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- threats: [
- {
- framework: 'fake',
- tactic: {
- id: 'fakeId',
- name: 'fakeName',
- reference: 'fakeRef',
- },
- techniques: [
- {
- id: 'techniqueId',
- name: 'techniqueName',
- reference: 'techniqueRef',
- },
- ],
- },
- ],
- }).value.threats
- ).toMatchObject(expected);
- });
- test('threats is invalid when updated with missing property framework', () => {
- expect(
- updateRulesSchema.validate<
- Partial> & {
- threats: Array>>;
- }
- >({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- threats: [
- {
- tactic: {
- id: 'fakeId',
- name: 'fakeName',
- reference: 'fakeRef',
- },
- techniques: [
- {
- id: 'techniqueId',
- name: 'techniqueName',
- reference: 'techniqueRef',
- },
- ],
- },
- ],
- }).error
- ).toBeTruthy();
- });
- test('threats is invalid when updated with missing tactic sub-object', () => {
- expect(
- updateRulesSchema.validate<
- Partial> & {
- threats: Array>>;
- }
- >({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- threats: [
- {
- framework: 'fake',
- techniques: [
- {
- id: 'techniqueId',
- name: 'techniqueName',
- reference: 'techniqueRef',
- },
- ],
- },
- ],
- }).error
- ).toBeTruthy();
- });
- test('threats is invalid when updated with missing techniques', () => {
- expect(
- updateRulesSchema.validate<
- Partial> & {
- threats: Array>>;
- }
- >({
- id: 'rule-1',
- description: 'some description',
- from: 'now-5m',
- to: 'now',
- index: ['index-1'],
- name: 'some-name',
- severity: 'severity',
- interval: '5m',
- type: 'query',
- references: ['index-1'],
- query: 'some query',
- language: 'kuery',
- max_signals: 1,
- threats: [
- {
- framework: 'fake',
- tactic: {
- id: 'techniqueId',
- name: 'techniqueName',
- reference: 'techniqueRef',
- },
- },
- ],
- }).error
- ).toBeTruthy();
- });
- });
-
- describe('find rules schema', () => {
- test('empty objects do validate', () => {
- expect(findRulesSchema.validate>({}).error).toBeFalsy();
- });
-
- test('all values validate', () => {
- expect(
- findRulesSchema.validate>({
- per_page: 5,
- page: 1,
- sort_field: 'some field',
- fields: ['field 1', 'field 2'],
- filter: 'some filter',
- sort_order: 'asc',
- }).error
- ).toBeFalsy();
- });
-
- test('made up parameters do not validate', () => {
- expect(
- findRulesSchema.validate>({
- madeUp: 'hi',
- }).error
- ).toBeTruthy();
- });
-
- test('per_page validates', () => {
- expect(
- findRulesSchema.validate>({ per_page: 5 }).error
- ).toBeFalsy();
- });
-
- test('page validates', () => {
- expect(
- findRulesSchema.validate>({ page: 5 }).error
- ).toBeFalsy();
- });
-
- test('sort_field validates', () => {
- expect(
- findRulesSchema.validate>({ sort_field: 'some value' }).error
- ).toBeFalsy();
- });
-
- test('fields validates with a string', () => {
- expect(
- findRulesSchema.validate>({ fields: ['some value'] }).error
- ).toBeFalsy();
- });
-
- test('fields validates with multiple strings', () => {
- expect(
- findRulesSchema.validate>({
- fields: ['some value 1', 'some value 2'],
- }).error
- ).toBeFalsy();
- });
-
- test('fields does not validate with a number', () => {
- expect(
- findRulesSchema.validate> & { fields: number[] }>({
- fields: [5],
- }).error
- ).toBeTruthy();
- });
-
- test('per page has a default of 20', () => {
- expect(findRulesSchema.validate>({}).value.per_page).toEqual(20);
- });
-
- test('page has a default of 1', () => {
- expect(findRulesSchema.validate>({}).value.page).toEqual(1);
- });
-
- test('filter works with a string', () => {
- expect(
- findRulesSchema.validate>({
- filter: 'some value 1',
- }).error
- ).toBeFalsy();
- });
-
- test('filter does not work with a number', () => {
- expect(
- findRulesSchema.validate> & { filter: number }>({
- filter: 5,
- }).error
- ).toBeTruthy();
- });
-
- test('sort_order requires sort_field to work', () => {
- expect(
- findRulesSchema.validate>({
- sort_order: 'asc',
- }).error
- ).toBeTruthy();
- });
-
- test('sort_order and sort_field validate together', () => {
- expect(
- findRulesSchema.validate>({
- sort_order: 'asc',
- sort_field: 'some field',
- }).error
- ).toBeFalsy();
- });
-
- test('sort_order validates with desc and sort_field', () => {
- expect(
- findRulesSchema.validate>({
- sort_order: 'desc',
- sort_field: 'some field',
- }).error
- ).toBeFalsy();
- });
-
- test('sort_order does not validate with a string other than asc and desc', () => {
- expect(
- findRulesSchema.validate<
- Partial> & { sort_order: string }
- >({
- sort_order: 'some other string',
- sort_field: 'some field',
- }).error
- ).toBeTruthy();
- });
- });
-
- describe('queryRulesSchema', () => {
- test('empty objects do not validate', () => {
- expect(queryRulesSchema.validate>({}).error).toBeTruthy();
- });
-
- test('both rule_id and id being supplied dot not validate', () => {
- expect(
- queryRulesSchema.validate>({ rule_id: '1', id: '1' })
- .error
- ).toBeTruthy();
- });
-
- test('only id validates', () => {
- expect(
- queryRulesSchema.validate>({ id: '1' }).error
- ).toBeFalsy();
- });
-
- test('only rule_id validates', () => {
- expect(
- queryRulesSchema.validate>({ rule_id: '1' }).error
- ).toBeFalsy();
- });
- });
-
- describe('set signal status schema', () => {
- test('signal_ids and status is valid', () => {
- expect(
- setSignalsStatusSchema.validate>({
- signal_ids: ['somefakeid'],
- status: 'open',
- }).error
- ).toBeFalsy();
- });
-
- test('query and status is valid', () => {
- expect(
- setSignalsStatusSchema.validate>({
- query: {},
- status: 'open',
- }).error
- ).toBeFalsy();
- });
-
- test('signal_ids and missing status is invalid', () => {
- expect(
- setSignalsStatusSchema.validate>({
- signal_ids: ['somefakeid'],
- }).error
- ).toBeTruthy();
- });
-
- test('query and missing status is invalid', () => {
- expect(
- setSignalsStatusSchema.validate>({
- query: {},
- }).error
- ).toBeTruthy();
- });
-
- test('status is present but query or signal_ids is missing is invalid', () => {
- expect(
- setSignalsStatusSchema.validate>({
- status: 'closed',
- }).error
- ).toBeTruthy();
- });
-
- test('signal_ids is present but status has wrong value', () => {
- expect(
- setSignalsStatusSchema.validate<
- Partial<
- Omit & {
- status: string;
- }
- >
- >({
- status: 'fakeVal',
- }).error
- ).toBeTruthy();
- });
- });
-});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.ts
deleted file mode 100644
index 6ed6fdd2577d8..0000000000000
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.ts
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import Joi from 'joi';
-import { DEFAULT_MAX_SIGNALS } from '../../../../common/constants';
-
-/* eslint-disable @typescript-eslint/camelcase */
-const description = Joi.string();
-const enabled = Joi.boolean();
-const false_positives = Joi.array().items(Joi.string());
-const filters = Joi.array();
-const from = Joi.string();
-const immutable = Joi.boolean();
-const rule_id = Joi.string();
-const id = Joi.string();
-const index = Joi.array()
- .items(Joi.string())
- .single();
-const interval = Joi.string();
-const query = Joi.string();
-const language = Joi.string().valid('kuery', 'lucene');
-const output_index = Joi.string();
-const saved_id = Joi.string();
-const meta = Joi.object();
-const max_signals = Joi.number().greater(0);
-const name = Joi.string();
-const risk_score = Joi.number()
- .greater(-1)
- .less(101);
-const severity = Joi.string();
-const status = Joi.string().valid('open', 'closed');
-const to = Joi.string();
-const type = Joi.string().valid('query', 'saved_query');
-const queryFilter = Joi.string();
-const references = Joi.array()
- .items(Joi.string())
- .single();
-const per_page = Joi.number()
- .min(0)
- .default(20);
-const page = Joi.number()
- .min(1)
- .default(1);
-const signal_ids = Joi.array().items(Joi.string());
-const signal_status_query = Joi.object();
-const sort_field = Joi.string();
-const sort_order = Joi.string().valid('asc', 'desc');
-const tags = Joi.array().items(Joi.string());
-const fields = Joi.array()
- .items(Joi.string())
- .single();
-const threat_framework = Joi.string();
-const threat_tactic_id = Joi.string();
-const threat_tactic_name = Joi.string();
-const threat_tactic_reference = Joi.string();
-const threat_tactic = Joi.object({
- id: threat_tactic_id.required(),
- name: threat_tactic_name.required(),
- reference: threat_tactic_reference.required(),
-});
-const threat_technique_id = Joi.string();
-const threat_technique_name = Joi.string();
-const threat_technique_reference = Joi.string();
-const threat_technique = Joi.object({
- id: threat_technique_id.required(),
- name: threat_technique_name.required(),
- reference: threat_technique_reference.required(),
-});
-const threat_techniques = Joi.array().items(threat_technique.required());
-
-const threats = Joi.array().items(
- Joi.object({
- framework: threat_framework.required(),
- tactic: threat_tactic.required(),
- techniques: threat_techniques.required(),
- })
-);
-/* eslint-enable @typescript-eslint/camelcase */
-
-export const createRulesSchema = Joi.object({
- description: description.required(),
- enabled: enabled.default(true),
- false_positives: false_positives.default([]),
- filters,
- from: from.required(),
- rule_id,
- immutable: immutable.default(false),
- index,
- interval: interval.default('5m'),
- query: query.allow('').default(''),
- language: language.default('kuery'),
- output_index,
- saved_id: saved_id.when('type', {
- is: 'saved_query',
- then: Joi.required(),
- otherwise: Joi.forbidden(),
- }),
- meta,
- risk_score: risk_score.required(),
- max_signals: max_signals.default(DEFAULT_MAX_SIGNALS),
- name: name.required(),
- severity: severity.required(),
- tags: tags.default([]),
- to: to.required(),
- type: type.required(),
- threats: threats.default([]),
- references: references.default([]),
-});
-
-export const updateRulesSchema = Joi.object({
- description,
- enabled,
- false_positives,
- filters,
- from,
- rule_id,
- id,
- immutable,
- index,
- interval,
- query: query.allow(''),
- language,
- output_index,
- saved_id,
- meta,
- risk_score,
- max_signals,
- name,
- severity,
- tags,
- to,
- type,
- threats,
- references,
-}).xor('id', 'rule_id');
-
-export const queryRulesSchema = Joi.object({
- rule_id,
- id,
-}).xor('id', 'rule_id');
-
-export const findRulesSchema = Joi.object({
- fields,
- filter: queryFilter,
- per_page,
- page,
- sort_field: Joi.when(Joi.ref('sort_order'), {
- is: Joi.exist(),
- then: sort_field.required(),
- otherwise: sort_field.optional(),
- }),
- sort_order,
-});
-
-export const setSignalsStatusSchema = Joi.object({
- signal_ids,
- query: signal_status_query,
- status: status.required(),
-}).xor('signal_ids', 'query');
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/create_rules_schema.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/create_rules_schema.test.ts
new file mode 100644
index 0000000000000..4efea69db1f41
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/create_rules_schema.test.ts
@@ -0,0 +1,1047 @@
+/*
+ * 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 { createRulesSchema } from './create_rules_schema';
+import { UpdateRuleAlertParamsRest } from '../../rules/types';
+import { ThreatParams, RuleAlertParamsRest } from '../../types';
+
+describe('create rules schema', () => {
+ test('empty objects do not validate', () => {
+ expect(createRulesSchema.validate>({}).error).toBeTruthy();
+ });
+
+ test('made up values do not validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ madeUp: 'hi',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('[rule_id] does not validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('[rule_id, description] does not validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ description: 'some description',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('[rule_id, description, from] does not validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ description: 'some description',
+ from: 'now-5m',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('[rule_id, description, from, to] does not validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('[rule_id, description, from, to, name] does not validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ name: 'some-name',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('[rule_id, description, from, to, name, severity] does not validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ name: 'some-name',
+ severity: 'severity',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('[rule_id, description, from, to, name, severity, type] does not validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ name: 'some-name',
+ severity: 'severity',
+ type: 'query',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('[rule_id, description, from, to, name, severity, type, interval] does not validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('[rule_id, description, from, to, name, severity, type, interval, index] does not validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ name: 'some-name',
+ severity: 'severity',
+ type: 'query',
+ interval: '5m',
+ index: ['index-1'],
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('[rule_id, description, from, to, name, severity, type, query, index, interval] does validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ name: 'some-name',
+ severity: 'severity',
+ type: 'query',
+ query: 'some query',
+ index: ['index-1'],
+ interval: '5m',
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('[rule_id, description, from, to, index, name, severity, interval, type, query, language] does not validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ query: 'some query',
+ language: 'kuery',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score] does validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ query: 'some query',
+ language: 'kuery',
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score, output_index] does validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ query: 'some query',
+ language: 'kuery',
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score] does validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ risk_score: 50,
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index] does validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ }).error
+ ).toBeFalsy();
+ });
+ test('You can send in an empty array to threats', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ threats: [],
+ }).error
+ ).toBeFalsy();
+ });
+ test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index, threats] does validate', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ threats: [
+ {
+ framework: 'someFramework',
+ tactic: {
+ id: 'fakeId',
+ name: 'fakeName',
+ reference: 'fakeRef',
+ },
+ techniques: [
+ {
+ id: 'techniqueId',
+ name: 'techniqueName',
+ reference: 'techniqueRef',
+ },
+ ],
+ },
+ ],
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('allows references to be sent as valid', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('defaults references to an array', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ query: 'some-query',
+ language: 'kuery',
+ }).value.references
+ ).toEqual([]);
+ });
+
+ test('references cannot be numbers', () => {
+ expect(
+ createRulesSchema.validate<
+ Partial> & { references: number[] }
+ >({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ query: 'some-query',
+ language: 'kuery',
+ references: [5],
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('indexes cannot be numbers', () => {
+ expect(
+ createRulesSchema.validate> & { index: number[] }>(
+ {
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: [5],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ query: 'some-query',
+ language: 'kuery',
+ }
+ ).error
+ ).toBeTruthy();
+ });
+
+ test('defaults interval to 5 min', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ type: 'query',
+ }).value.interval
+ ).toEqual('5m');
+ });
+
+ test('defaults max signals to 100', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ }).value.max_signals
+ ).toEqual(100);
+ });
+
+ test('saved_id is required when type is saved_query and will not validate without out', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'saved_query',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('saved_id is required when type is saved_query and validates with it', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ risk_score: 50,
+ output_index: '.siem-signals',
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'saved_query',
+ saved_id: 'some id',
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('saved_query type can have filters with it', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'saved_query',
+ saved_id: 'some id',
+ filters: [],
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('filters cannot be a string', () => {
+ expect(
+ createRulesSchema.validate<
+ Partial & { filters: string }>
+ >({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'saved_query',
+ saved_id: 'some id',
+ filters: 'some string',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('language validates with kuery', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('language validates with lucene', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ risk_score: 50,
+ output_index: '.siem-signals',
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'lucene',
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('language does not validate with something made up', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'something-made-up',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('max_signals cannot be negative', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: -1,
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('max_signals cannot be zero', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 0,
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('max_signals can be 1', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('You can optionally send in an array of tags', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ tags: ['tag_1', 'tag_2'],
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('You cannot send in an array of tags that are numbers', () => {
+ expect(
+ createRulesSchema.validate> & { tags: number[] }>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ tags: [0, 1, 2],
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('You cannot send in an array of threats that are missing "framework"', () => {
+ expect(
+ createRulesSchema.validate<
+ Partial> & {
+ threats: Array>>;
+ }
+ >({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ threats: [
+ {
+ tactic: {
+ id: 'fakeId',
+ name: 'fakeName',
+ reference: 'fakeRef',
+ },
+ techniques: [
+ {
+ id: 'techniqueId',
+ name: 'techniqueName',
+ reference: 'techniqueRef',
+ },
+ ],
+ },
+ ],
+ }).error
+ ).toBeTruthy();
+ });
+ test('You cannot send in an array of threats that are missing "tactic"', () => {
+ expect(
+ createRulesSchema.validate<
+ Partial> & {
+ threats: Array>>;
+ }
+ >({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ threats: [
+ {
+ framework: 'fake',
+ techniques: [
+ {
+ id: 'techniqueId',
+ name: 'techniqueName',
+ reference: 'techniqueRef',
+ },
+ ],
+ },
+ ],
+ }).error
+ ).toBeTruthy();
+ });
+ test('You cannot send in an array of threats that are missing "techniques"', () => {
+ expect(
+ createRulesSchema.validate<
+ Partial> & {
+ threats: Array>>;
+ }
+ >({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ threats: [
+ {
+ framework: 'fake',
+ tactic: {
+ id: 'fakeId',
+ name: 'fakeName',
+ reference: 'fakeRef',
+ },
+ },
+ ],
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('You can optionally send in an array of false positives', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ false_positives: ['false_1', 'false_2'],
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('You cannot send in an array of false positives that are numbers', () => {
+ expect(
+ createRulesSchema.validate<
+ Partial> & { false_positives: number[] }
+ >({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ false_positives: [5, 4],
+ from: 'now-5m',
+ to: 'now',
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('You can optionally set the immutable to be true', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ immutable: true,
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('You cannot set the immutable to be a number', () => {
+ expect(
+ createRulesSchema.validate<
+ Partial> & { immutable: number }
+ >({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ immutable: 5,
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('You cannot set the risk_score to 101', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 101,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ immutable: true,
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('You cannot set the risk_score to -1', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: -1,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ immutable: true,
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('You can set the risk_score to 0', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 0,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ immutable: true,
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('You can set the risk_score to 100', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 100,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ immutable: true,
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('You can set meta to any object you want', () => {
+ expect(
+ createRulesSchema.validate>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ immutable: true,
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ meta: {
+ somethingMadeUp: { somethingElse: true },
+ },
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('You cannot create meta as a string', () => {
+ expect(
+ createRulesSchema.validate & { meta: string }>>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ immutable: true,
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ query: 'some query',
+ language: 'kuery',
+ max_signals: 1,
+ meta: 'should not work',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('You can omit the query string when filters are present', () => {
+ expect(
+ createRulesSchema.validate & { meta: string }>>({
+ rule_id: 'rule-1',
+ output_index: '.siem-signals',
+ risk_score: 50,
+ description: 'some description',
+ from: 'now-5m',
+ to: 'now',
+ immutable: true,
+ index: ['index-1'],
+ name: 'some-name',
+ severity: 'severity',
+ interval: '5m',
+ type: 'query',
+ references: ['index-1'],
+ language: 'kuery',
+ filters: [],
+ max_signals: 1,
+ }).error
+ ).toBeFalsy();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/create_rules_schema.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/create_rules_schema.ts
new file mode 100644
index 0000000000000..ccda7256d2eeb
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/create_rules_schema.ts
@@ -0,0 +1,67 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import Joi from 'joi';
+
+/* eslint-disable @typescript-eslint/camelcase */
+import {
+ enabled,
+ description,
+ false_positives,
+ filters,
+ from,
+ immutable,
+ index,
+ rule_id,
+ interval,
+ query,
+ language,
+ output_index,
+ saved_id,
+ meta,
+ risk_score,
+ max_signals,
+ name,
+ severity,
+ tags,
+ to,
+ type,
+ threats,
+ references,
+} from './schemas';
+/* eslint-enable @typescript-eslint/camelcase */
+
+import { DEFAULT_MAX_SIGNALS } from '../../../../../common/constants';
+
+export const createRulesSchema = Joi.object({
+ description: description.required(),
+ enabled: enabled.default(true),
+ false_positives: false_positives.default([]),
+ filters,
+ from: from.required(),
+ rule_id,
+ immutable: immutable.default(false),
+ index,
+ interval: interval.default('5m'),
+ query: query.allow('').default(''),
+ language: language.default('kuery'),
+ output_index,
+ saved_id: saved_id.when('type', {
+ is: 'saved_query',
+ then: Joi.required(),
+ otherwise: Joi.forbidden(),
+ }),
+ meta,
+ risk_score: risk_score.required(),
+ max_signals: max_signals.default(DEFAULT_MAX_SIGNALS),
+ name: name.required(),
+ severity: severity.required(),
+ tags: tags.default([]),
+ to: to.required(),
+ type: type.required(),
+ threats: threats.default([]),
+ references: references.default([]),
+});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/find_rules_schema.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/find_rules_schema.test.ts
new file mode 100644
index 0000000000000..14b3bdb298739
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/find_rules_schema.test.ts
@@ -0,0 +1,136 @@
+/*
+ * 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 { findRulesSchema } from './find_rules_schema';
+import { FindParamsRest } from '../../rules/types';
+
+describe('find rules schema', () => {
+ test('empty objects do validate', () => {
+ expect(findRulesSchema.validate>({}).error).toBeFalsy();
+ });
+
+ test('all values validate', () => {
+ expect(
+ findRulesSchema.validate>({
+ per_page: 5,
+ page: 1,
+ sort_field: 'some field',
+ fields: ['field 1', 'field 2'],
+ filter: 'some filter',
+ sort_order: 'asc',
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('made up parameters do not validate', () => {
+ expect(
+ findRulesSchema.validate>({
+ madeUp: 'hi',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('per_page validates', () => {
+ expect(
+ findRulesSchema.validate>({ per_page: 5 }).error
+ ).toBeFalsy();
+ });
+
+ test('page validates', () => {
+ expect(
+ findRulesSchema.validate>({ page: 5 }).error
+ ).toBeFalsy();
+ });
+
+ test('sort_field validates', () => {
+ expect(
+ findRulesSchema.validate>({ sort_field: 'some value' }).error
+ ).toBeFalsy();
+ });
+
+ test('fields validates with a string', () => {
+ expect(
+ findRulesSchema.validate>({ fields: ['some value'] }).error
+ ).toBeFalsy();
+ });
+
+ test('fields validates with multiple strings', () => {
+ expect(
+ findRulesSchema.validate>({
+ fields: ['some value 1', 'some value 2'],
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('fields does not validate with a number', () => {
+ expect(
+ findRulesSchema.validate> & { fields: number[] }>({
+ fields: [5],
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('per page has a default of 20', () => {
+ expect(findRulesSchema.validate>({}).value.per_page).toEqual(20);
+ });
+
+ test('page has a default of 1', () => {
+ expect(findRulesSchema.validate>({}).value.page).toEqual(1);
+ });
+
+ test('filter works with a string', () => {
+ expect(
+ findRulesSchema.validate>({
+ filter: 'some value 1',
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('filter does not work with a number', () => {
+ expect(
+ findRulesSchema.validate> & { filter: number }>({
+ filter: 5,
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('sort_order requires sort_field to work', () => {
+ expect(
+ findRulesSchema.validate>({
+ sort_order: 'asc',
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('sort_order and sort_field validate together', () => {
+ expect(
+ findRulesSchema.validate>({
+ sort_order: 'asc',
+ sort_field: 'some field',
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('sort_order validates with desc and sort_field', () => {
+ expect(
+ findRulesSchema.validate>({
+ sort_order: 'desc',
+ sort_field: 'some field',
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('sort_order does not validate with a string other than asc and desc', () => {
+ expect(
+ findRulesSchema.validate<
+ Partial> & { sort_order: string }
+ >({
+ sort_order: 'some other string',
+ sort_field: 'some field',
+ }).error
+ ).toBeTruthy();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/find_rules_schema.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/find_rules_schema.ts
new file mode 100644
index 0000000000000..3cc5b9ca44530
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/find_rules_schema.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import Joi from 'joi';
+
+/* eslint-disable @typescript-eslint/camelcase */
+import { queryFilter, fields, per_page, page, sort_field, sort_order } from './schemas';
+/* eslint-enable @typescript-eslint/camelcase */
+
+export const findRulesSchema = Joi.object({
+ fields,
+ filter: queryFilter,
+ per_page,
+ page,
+ sort_field: Joi.when(Joi.ref('sort_order'), {
+ is: Joi.exist(),
+ then: sort_field.required(),
+ otherwise: sort_field.optional(),
+ }),
+ sort_order,
+});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/query_rules_schema.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/query_rules_schema.test.ts
new file mode 100644
index 0000000000000..6c4e96abd2b98
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/query_rules_schema.test.ts
@@ -0,0 +1,32 @@
+/*
+ * 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 { queryRulesSchema } from './query_rules_schema';
+import { UpdateRuleAlertParamsRest } from '../../rules/types';
+
+describe('queryRulesSchema', () => {
+ test('empty objects do not validate', () => {
+ expect(queryRulesSchema.validate>({}).error).toBeTruthy();
+ });
+
+ test('both rule_id and id being supplied dot not validate', () => {
+ expect(
+ queryRulesSchema.validate>({ rule_id: '1', id: '1' }).error
+ ).toBeTruthy();
+ });
+
+ test('only id validates', () => {
+ expect(
+ queryRulesSchema.validate>({ id: '1' }).error
+ ).toBeFalsy();
+ });
+
+ test('only rule_id validates', () => {
+ expect(
+ queryRulesSchema.validate>({ rule_id: '1' }).error
+ ).toBeFalsy();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/query_rules_schema.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/query_rules_schema.ts
new file mode 100644
index 0000000000000..86a731699d1ea
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/query_rules_schema.ts
@@ -0,0 +1,16 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import Joi from 'joi';
+
+/* eslint-disable @typescript-eslint/camelcase */
+import { rule_id, id } from './schemas';
+/* eslint-enable @typescript-eslint/camelcase */
+
+export const queryRulesSchema = Joi.object({
+ rule_id,
+ id,
+}).xor('id', 'rule_id');
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/schemas.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/schemas.ts
new file mode 100644
index 0000000000000..5ab8ea3b8af3e
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/schemas.ts
@@ -0,0 +1,79 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import Joi from 'joi';
+
+/* eslint-disable @typescript-eslint/camelcase */
+export const description = Joi.string();
+export const enabled = Joi.boolean();
+export const false_positives = Joi.array().items(Joi.string());
+export const filters = Joi.array();
+export const from = Joi.string();
+export const immutable = Joi.boolean();
+export const rule_id = Joi.string();
+export const id = Joi.string();
+export const index = Joi.array()
+ .items(Joi.string())
+ .single();
+export const interval = Joi.string();
+export const query = Joi.string();
+export const language = Joi.string().valid('kuery', 'lucene');
+export const output_index = Joi.string();
+export const saved_id = Joi.string();
+export const meta = Joi.object();
+export const max_signals = Joi.number().greater(0);
+export const name = Joi.string();
+export const risk_score = Joi.number()
+ .greater(-1)
+ .less(101);
+export const severity = Joi.string();
+export const status = Joi.string().valid('open', 'closed');
+export const to = Joi.string();
+export const type = Joi.string().valid('query', 'saved_query');
+export const queryFilter = Joi.string();
+export const references = Joi.array()
+ .items(Joi.string())
+ .single();
+export const per_page = Joi.number()
+ .min(0)
+ .default(20);
+export const page = Joi.number()
+ .min(1)
+ .default(1);
+export const signal_ids = Joi.array().items(Joi.string());
+export const signal_status_query = Joi.object();
+export const sort_field = Joi.string();
+export const sort_order = Joi.string().valid('asc', 'desc');
+export const tags = Joi.array().items(Joi.string());
+export const fields = Joi.array()
+ .items(Joi.string())
+ .single();
+export const threat_framework = Joi.string();
+export const threat_tactic_id = Joi.string();
+export const threat_tactic_name = Joi.string();
+export const threat_tactic_reference = Joi.string();
+export const threat_tactic = Joi.object({
+ id: threat_tactic_id.required(),
+ name: threat_tactic_name.required(),
+ reference: threat_tactic_reference.required(),
+});
+export const threat_technique_id = Joi.string();
+export const threat_technique_name = Joi.string();
+export const threat_technique_reference = Joi.string();
+export const threat_technique = Joi.object({
+ id: threat_technique_id.required(),
+ name: threat_technique_name.required(),
+ reference: threat_technique_reference.required(),
+});
+export const threat_techniques = Joi.array().items(threat_technique.required());
+
+export const threats = Joi.array().items(
+ Joi.object({
+ framework: threat_framework.required(),
+ tactic: threat_tactic.required(),
+ techniques: threat_techniques.required(),
+ })
+);
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/set_signal_status_schema.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/set_signal_status_schema.test.ts
new file mode 100644
index 0000000000000..b586b4666bfee
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/set_signal_status_schema.test.ts
@@ -0,0 +1,66 @@
+/*
+ * 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 { setSignalsStatusSchema } from './set_signal_status_schema';
+import { SignalsRestParams } from '../../signals/types';
+
+describe('set signal status schema', () => {
+ test('signal_ids and status is valid', () => {
+ expect(
+ setSignalsStatusSchema.validate>({
+ signal_ids: ['somefakeid'],
+ status: 'open',
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('query and status is valid', () => {
+ expect(
+ setSignalsStatusSchema.validate>({
+ query: {},
+ status: 'open',
+ }).error
+ ).toBeFalsy();
+ });
+
+ test('signal_ids and missing status is invalid', () => {
+ expect(
+ setSignalsStatusSchema.validate>({
+ signal_ids: ['somefakeid'],
+ }).error
+ ).toBeTruthy();
+ });
+
+ test('query and missing status is invalid', () => {
+ expect(
+ setSignalsStatusSchema.validate