-
+
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover_state.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover_state.ts
index 981855d1ee77..d9e1850cd6a2 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover_state.ts
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover_state.ts
@@ -28,7 +28,7 @@ import {
import { esFilters, Filter, Query } from '../../../../../../../plugins/data/public';
import { migrateLegacyQuery } from '../../../../../../../plugins/kibana_legacy/public';
-interface AppState {
+export interface AppState {
/**
* Columns displayed in the table
*/
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/_index.scss b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/_index.scss
index 7161560f8fda..6ddd2e0eae8e 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/_index.scss
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/_index.scss
@@ -1,2 +1,2 @@
@import 'fetch_error/index';
-@import 'field_chooser/index';
+@import 'sidebar/index';
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/_field_chooser.scss b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/_field_chooser.scss
deleted file mode 100644
index b05775c4ee95..000000000000
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/_field_chooser.scss
+++ /dev/null
@@ -1,36 +0,0 @@
-.dscFieldChooser {
- padding-left: $euiSizeS !important;
- padding-right: $euiSizeS !important;
-}
-
-.dscFieldChooser__toggle {
- color: $euiColorMediumShade;
- margin-left: $euiSizeS !important;
-}
-
-.dscFieldName {
- color: $euiColorDarkShade;
-}
-
-
-/*
- Fixes EUI known issue https://github.com/elastic/eui/issues/1749
-*/
-.dscProgressBarTooltip__anchor {
- display: block;
-}
-
-.dscToggleFieldFilterButton {
- width: calc(100% - #{$euiSizeS});
- color: $euiColorPrimary;
- padding-left: $euiSizeXS;
- margin-left: $euiSizeXS;
-}
-
-.dscFieldSearch__filterWrapper {
- flex-grow: 0;
-}
-
-.dscFieldSearch__formWrapper {
- padding: $euiSizeM;
-}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/_index.scss b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/_index.scss
deleted file mode 100644
index 91daed8ea048..000000000000
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/_index.scss
+++ /dev/null
@@ -1 +0,0 @@
-@import 'field_chooser';
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field.html b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field.html
deleted file mode 100644
index 06e7cc507541..000000000000
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field.js
deleted file mode 100644
index f7f219a28749..000000000000
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field.js
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import $ from 'jquery';
-import _ from 'lodash';
-import { i18n } from '@kbn/i18n';
-import { getServices } from '../../../kibana_services';
-import html from './discover_field.html';
-import './string_progress_bar';
-import detailsHtml from './lib/detail_views/string.html';
-
-export function createDiscoverFieldDirective($compile) {
- return {
- restrict: 'E',
- template: html,
- replace: true,
- scope: {
- field: '=',
- onAddField: '=',
- onAddFilter: '=',
- onRemoveField: '=',
- onShowDetails: '=',
- },
- link: function($scope, $elem) {
- let detailsElem;
- let detailScope;
-
- const init = function() {
- if ($scope.field.details) {
- $scope.toggleDetails($scope.field, true);
- }
-
- $scope.addRemoveButtonLabel = $scope.field.display
- ? i18n.translate('kbn.discover.fieldChooser.discoverField.removeButtonLabel', {
- defaultMessage: 'remove',
- })
- : i18n.translate('kbn.discover.fieldChooser.discoverField.addButtonLabel', {
- defaultMessage: 'add',
- });
- };
-
- const getWarnings = function(field) {
- let warnings = [];
-
- if (field.scripted) {
- warnings.push(
- i18n.translate(
- 'kbn.discover.fieldChooser.discoverField.scriptedFieldsTakeLongExecuteDescription',
- {
- defaultMessage: 'Scripted fields can take a long time to execute.',
- }
- )
- );
- }
-
- if (warnings.length > 1) {
- warnings = warnings.map(function(warning, i) {
- return (i > 0 ? '\n' : '') + (i + 1) + ' - ' + warning;
- });
- }
-
- return warnings;
- };
-
- $scope.canVisualize = getServices().capabilities.visualize.show;
-
- $scope.toggleDisplay = function(field) {
- if (field.display) {
- $scope.onRemoveField(field.name);
- } else {
- $scope.onAddField(field.name);
- }
-
- if (field.details) {
- $scope.toggleDetails(field);
- }
- };
-
- $scope.onClickToggleDetails = function onClickToggleDetails($event, field) {
- // Do nothing if the event originated from a child.
- if ($event.currentTarget !== $event.target) {
- $event.preventDefault();
- }
-
- $scope.toggleDetails(field);
- };
-
- $scope.toggleDetails = function(field, recompute) {
- if (_.isUndefined(field.details) || recompute) {
- $scope.onShowDetails(field, recompute);
- detailScope = $scope.$new();
- detailScope.warnings = getWarnings(field);
- detailScope.getBucketAriaLabel = bucket => {
- return i18n.translate('kbn.discover.fieldChooser.discoverField.bucketAriaLabel', {
- defaultMessage: 'Value: {value}',
- values: {
- value:
- bucket.display === ''
- ? i18n.translate('kbn.discover.fieldChooser.discoverField.emptyStringText', {
- defaultMessage: 'Empty string',
- })
- : bucket.display,
- },
- });
- };
-
- detailsElem = $(detailsHtml);
- $compile(detailsElem)(detailScope);
- $elem.append(detailsElem).addClass('active');
- $elem.find('.dscSidebarItem').addClass('dscSidebarItem--active');
- } else {
- delete field.details;
- detailScope.$destroy();
- detailsElem.remove();
- $elem.removeClass('active');
- $elem.find('.dscSidebarItem').removeClass('dscSidebarItem--active');
- }
- };
-
- init();
- },
- };
-}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field_search_directive.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field_search_directive.ts
deleted file mode 100644
index 6d570349ee0c..000000000000
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field_search_directive.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { wrapInI18nContext } from '../../../kibana_services';
-import { DiscoverFieldSearch } from './discover_field_search';
-
-export function createFieldSearchDirective(reactDirective: any) {
- return reactDirective(wrapInI18nContext(DiscoverFieldSearch), [
- ['onChange', { watchDepth: 'reference' }],
- ['value', { watchDepth: 'value' }],
- ['types', { watchDepth: 'value' }],
- ]);
-}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/field_chooser.html b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/field_chooser.html
deleted file mode 100644
index fd63c26aa2bb..000000000000
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/field_chooser.html
+++ /dev/null
@@ -1,99 +0,0 @@
-
-
-
-
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/field_chooser.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/field_chooser.js
deleted file mode 100644
index 398728e51862..000000000000
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/field_chooser.js
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import _ from 'lodash';
-import $ from 'jquery';
-import rison from 'rison-node';
-import { fieldCalculator } from './lib/field_calculator';
-import './discover_field';
-import './discover_field_search_directive';
-import './discover_index_pattern_directive';
-import fieldChooserTemplate from './field_chooser.html';
-import {
- IndexPatternFieldList,
- KBN_FIELD_TYPES,
-} from '../../../../../../../../plugins/data/public';
-import { getMapsAppUrl, isFieldVisualizable, isMapsAppRegistered } from './lib/visualize_url_utils';
-import { getServices } from '../../../kibana_services';
-
-export function createFieldChooserDirective($location) {
- return {
- restrict: 'E',
- scope: {
- columns: '=',
- hits: '=',
- fieldCounts: '=',
- state: '=',
- indexPattern: '=',
- indexPatternList: '=',
- onAddField: '=',
- onAddFilter: '=',
- onRemoveField: '=',
- },
- template: fieldChooserTemplate,
- link: function($scope) {
- $scope.showFilter = false;
- $scope.toggleShowFilter = () => ($scope.showFilter = !$scope.showFilter);
- $scope.indexPatternList = _.sortBy($scope.indexPatternList, o => o.get('title'));
- const config = getServices().uiSettings;
-
- const filter = ($scope.filter = {
- props: ['type', 'aggregatable', 'searchable', 'missing', 'name'],
- defaults: {
- missing: true,
- type: 'any',
- name: '',
- },
- boolOpts: [
- { label: 'any', value: undefined },
- { label: 'yes', value: true },
- { label: 'no', value: false },
- ],
- reset: function() {
- filter.vals = _.clone(filter.defaults);
- },
- /**
- * filter for fields that are displayed / selected for the data table
- */
- isFieldFilteredAndDisplayed: function(field) {
- return field.display && isFieldFiltered(field);
- },
- /**
- * filter for fields that are not displayed / selected for the data table
- */
- isFieldFilteredAndNotDisplayed: function(field) {
- return !field.display && isFieldFiltered(field) && field.type !== '_source';
- },
- getActive: function() {
- return _.some(filter.props, function(prop) {
- return filter.vals[prop] !== filter.defaults[prop];
- });
- },
- });
-
- function isFieldFiltered(field) {
- const matchFilter = filter.vals.type === 'any' || field.type === filter.vals.type;
- const isAggregatable =
- filter.vals.aggregatable == null || field.aggregatable === filter.vals.aggregatable;
- const isSearchable =
- filter.vals.searchable == null || field.searchable === filter.vals.searchable;
- const scriptedOrMissing =
- !filter.vals.missing || field.type === '_source' || field.scripted || field.rowCount > 0;
- const matchName = !filter.vals.name || field.name.indexOf(filter.vals.name) !== -1;
-
- return matchFilter && isAggregatable && isSearchable && scriptedOrMissing && matchName;
- }
-
- $scope.setFilterValue = (name, value) => {
- filter.vals[name] = value;
- };
-
- $scope.filtersActive = 0;
-
- // set the initial values to the defaults
- filter.reset();
-
- $scope.$watchCollection('filter.vals', function() {
- filter.active = filter.getActive();
- if (filter.vals) {
- let count = 0;
- Object.keys(filter.vals).forEach(key => {
- if (key === 'missing' || key === 'name') {
- return;
- }
- const value = filter.vals[key];
- if ((value && value !== 'any') || value === false) {
- count++;
- }
- });
- $scope.filtersActive = count;
- }
- });
-
- $scope.$watchMulti(['[]fieldCounts', '[]columns', '[]hits'], function(cur, prev) {
- const newHits = cur[2] !== prev[2];
- let fields = $scope.fields;
- const columns = $scope.columns || [];
- const fieldCounts = $scope.fieldCounts;
-
- if (!fields || newHits) {
- $scope.fields = fields = getFields();
- }
-
- if (!fields) return;
-
- // group the fields into popular and up-popular lists
- _.chain(fields)
- .each(function(field) {
- field.displayOrder = _.indexOf(columns, field.name) + 1;
- field.display = !!field.displayOrder;
- field.rowCount = fieldCounts[field.name];
- })
- .sortBy(function(field) {
- return (field.count || 0) * -1;
- })
- .groupBy(function(field) {
- if (field.display) return 'selected';
- return field.count > 0 ? 'popular' : 'unpopular';
- })
- .tap(function(groups) {
- groups.selected = _.sortBy(groups.selected || [], 'displayOrder');
-
- groups.popular = groups.popular || [];
- groups.unpopular = groups.unpopular || [];
-
- // move excess popular fields to un-popular list
- const extras = groups.popular.splice(config.get('fields:popularLimit'));
- groups.unpopular = extras.concat(groups.unpopular);
- })
- .each(function(group, name) {
- $scope[name + 'Fields'] = _.sortBy(group, name === 'selected' ? 'display' : 'name');
- })
- .commit();
-
- // include undefined so the user can clear the filter
- $scope.fieldTypes = _.union(['any'], _.pluck(fields, 'type'));
- });
-
- $scope.increaseFieldCounter = function(fieldName) {
- $scope.indexPattern.popularizeField(fieldName, 1);
- };
-
- function getVisualizeUrl(field) {
- if (!$scope.state) {
- return '';
- }
-
- if (
- (field.type === KBN_FIELD_TYPES.GEO_POINT || field.type === KBN_FIELD_TYPES.GEO_SHAPE) &&
- isMapsAppRegistered()
- ) {
- return getMapsAppUrl(field, $scope.indexPattern, $scope.state, $scope.columns);
- }
-
- let agg = {};
- const isGeoPoint = field.type === KBN_FIELD_TYPES.GEO_POINT;
- const type = isGeoPoint ? 'tile_map' : 'histogram';
- // If we're visualizing a date field, and our index is time based (and thus has a time filter),
- // then run a date histogram
- if (field.type === 'date' && $scope.indexPattern.timeFieldName === field.name) {
- agg = {
- type: 'date_histogram',
- schema: 'segment',
- params: {
- field: field.name,
- interval: 'auto',
- },
- };
- } else if (isGeoPoint) {
- agg = {
- type: 'geohash_grid',
- schema: 'segment',
- params: {
- field: field.name,
- precision: 3,
- },
- };
- } else {
- agg = {
- type: 'terms',
- schema: 'segment',
- params: {
- field: field.name,
- size: parseInt(config.get('discover:aggs:terms:size'), 10),
- orderBy: '2',
- },
- };
- }
-
- return (
- '#/visualize/create?' +
- $.param(
- _.assign(_.clone($location.search()), {
- indexPattern: $scope.state.index,
- type: type,
- _a: rison.encode({
- filters: $scope.state.filters || [],
- query: $scope.state.query || undefined,
- vis: {
- type: type,
- aggs: [{ schema: 'metric', type: 'count', id: '2' }, agg],
- },
- }),
- })
- )
- );
- }
-
- $scope.computeDetails = function(field, recompute) {
- if (_.isUndefined(field.details) || recompute) {
- field.details = {
- visualizeUrl: isFieldVisualizable(field) ? getVisualizeUrl(field) : null,
- ...fieldCalculator.getFieldValueCounts({
- hits: $scope.hits,
- field: field,
- count: 5,
- grouped: false,
- }),
- };
- _.each(field.details.buckets, function(bucket) {
- bucket.display = field.format.convert(bucket.value);
- });
- $scope.increaseFieldCounter(field, 1);
- } else {
- delete field.details;
- }
- };
-
- function getFields() {
- const prevFields = $scope.fields;
- const indexPattern = $scope.indexPattern;
- const hits = $scope.hits;
- const fieldCounts = $scope.fieldCounts;
-
- if (!indexPattern || !hits || !fieldCounts) return;
-
- const fieldSpecs = indexPattern.fields.slice(0);
- const fieldNamesInDocs = _.keys(fieldCounts);
- const fieldNamesInIndexPattern = _.map(indexPattern.fields, 'name');
-
- _.difference(fieldNamesInDocs, fieldNamesInIndexPattern).forEach(function(
- unknownFieldName
- ) {
- fieldSpecs.push({
- name: unknownFieldName,
- type: 'unknown',
- });
- });
-
- const fields = new IndexPatternFieldList(indexPattern, fieldSpecs);
-
- if (prevFields) {
- fields.forEach(function(field) {
- field.details = (prevFields.getByName(field.name) || {}).details;
- });
- }
-
- return fields;
- }
- },
- };
-}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/lib/detail_views/string.html b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/lib/detail_views/string.html
deleted file mode 100644
index 333dc472e956..000000000000
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/lib/detail_views/string.html
+++ /dev/null
@@ -1,106 +0,0 @@
- );
+ return { comp, props };
+}
+
+describe('discover sidebar field', function() {
+ it('should allow selecting fields', function() {
+ const { comp, props } = getComponent();
+ findTestSubject(comp, 'fieldToggle-bytes').simulate('click');
+ expect(props.onAddField).toHaveBeenCalledWith('bytes');
+ });
+ it('should allow deselecting fields', function() {
+ const { comp, props } = getComponent(true);
+ findTestSubject(comp, 'fieldToggle-bytes').simulate('click');
+ expect(props.onRemoveField).toHaveBeenCalledWith('bytes');
+ });
+ it('should trigger onShowDetails', function() {
+ const { comp, props } = getComponent();
+ findTestSubject(comp, 'field-bytes-showDetails').simulate('click');
+ expect(props.onShowDetails).toHaveBeenCalledWith(true, props.field);
+ });
+});
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field.tsx
new file mode 100644
index 000000000000..f7acb751c487
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field.tsx
@@ -0,0 +1,186 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React from 'react';
+import { EuiButton, EuiToolTip, EuiText } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { DiscoverFieldDetails } from './discover_field_details';
+import { FieldIcon } from '../../../../../../../../plugins/kibana_react/public';
+import { FieldDetails } from './types';
+import { IndexPatternField, IndexPattern } from '../../../../../../../../plugins/data/public';
+import { shortenDottedString } from '../../helpers';
+import { getFieldTypeName } from './lib/get_field_type_name';
+
+export interface DiscoverFieldProps {
+ /**
+ * The displayed field
+ */
+ field: IndexPatternField;
+ /**
+ * The currently selected index pattern
+ */
+ indexPattern: IndexPattern;
+ /**
+ * Callback to add/select the field
+ */
+ onAddField: (fieldName: string) => void;
+ /**
+ * Callback to add a filter to filter bar
+ */
+ onAddFilter: (field: IndexPatternField | string, value: string, type: '+' | '-') => void;
+ /**
+ * Callback to remove/deselect a the field
+ * @param fieldName
+ */
+ onRemoveField: (fieldName: string) => void;
+ /**
+ * Callback to hide/show details, buckets of the field
+ */
+ onShowDetails: (show: boolean, field: IndexPatternField) => void;
+ /**
+ * Determines, whether details of the field are displayed
+ */
+ showDetails: boolean;
+ /**
+ * Retrieve details data for the field
+ */
+ getDetails: (field: IndexPatternField) => FieldDetails;
+ /**
+ * Determines whether the field is selected
+ */
+ selected?: boolean;
+ /**
+ * Determines whether the field name is shortened test.sub1.sub2 = t.s.sub2
+ */
+ useShortDots?: boolean;
+}
+
+export function DiscoverField({
+ field,
+ indexPattern,
+ onAddField,
+ onRemoveField,
+ onAddFilter,
+ onShowDetails,
+ showDetails,
+ getDetails,
+ selected,
+ useShortDots,
+}: DiscoverFieldProps) {
+ const addLabel = i18n.translate('kbn.discover.fieldChooser.discoverField.addButtonLabel', {
+ defaultMessage: 'Add',
+ });
+ const addLabelAria = i18n.translate(
+ 'kbn.discover.fieldChooser.discoverField.addButtonAriaLabel',
+ {
+ defaultMessage: 'Add {field} to table',
+ values: { field: field.name },
+ }
+ );
+ const removeLabel = i18n.translate('kbn.discover.fieldChooser.discoverField.removeButtonLabel', {
+ defaultMessage: 'Remove',
+ });
+ const removeLabelAria = i18n.translate(
+ 'kbn.discover.fieldChooser.discoverField.removeButtonAriaLabel',
+ {
+ defaultMessage: 'Remove {field} from table',
+ values: { field: field.name },
+ }
+ );
+
+ const toggleDisplay = (f: IndexPatternField) => {
+ if (selected) {
+ onRemoveField(f.name);
+ } else {
+ onAddField(f.name);
+ }
+ };
+
+ return (
+ <>
+
+ )}
+ >
+ );
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field_bucket.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field_bucket.tsx
new file mode 100644
index 000000000000..5a2b855828f5
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field_bucket.tsx
@@ -0,0 +1,99 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React from 'react';
+import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { StringFieldProgressBar } from './string_progress_bar';
+import { Bucket } from './types';
+import { IndexPatternField } from '../../../../../../../../plugins/data/public';
+
+interface Props {
+ bucket: Bucket;
+ field: IndexPatternField;
+ onAddFilter: (field: IndexPatternField | string, value: string, type: '+' | '-') => void;
+}
+
+export function DiscoverFieldBucket({ field, bucket, onAddFilter }: Props) {
+ const emptyTxt = i18n.translate('kbn.discover.fieldChooser.detailViews.emptyStringText', {
+ defaultMessage: 'Empty string',
+ });
+ const addLabel = i18n.translate(
+ 'kbn.discover.fieldChooser.detailViews.filterValueButtonAriaLabel',
+ {
+ defaultMessage: 'Filter for {field}: "{value}"',
+ values: { value: bucket.value, field: field.name },
+ }
+ );
+ const removeLabel = i18n.translate(
+ 'kbn.discover.fieldChooser.detailViews.filterOutValueButtonAriaLabel',
+ {
+ defaultMessage: 'Filter out {field}: "{value}"',
+ values: { value: bucket.value, field: field.name },
+ }
+ );
+
+ return (
+ <>
+
+
+
+ {bucket.display === '' ? emptyTxt : bucket.display}
+
+
+ {field.filterable && (
+
+
+ )}
+
+
+ >
+ );
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field_details.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field_details.tsx
new file mode 100644
index 000000000000..6266c2974571
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field_details.tsx
@@ -0,0 +1,98 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React from 'react';
+import { EuiLink, EuiSpacer, EuiIconTip, EuiText } from '@elastic/eui';
+import { FormattedMessage } from '@kbn/i18n/react';
+import { DiscoverFieldBucket } from './discover_field_bucket';
+import { getWarnings } from './lib/get_warnings';
+import { Bucket, FieldDetails } from './types';
+import { IndexPatternField, IndexPattern } from '../../../../../../../../plugins/data/public';
+
+interface DiscoverFieldDetailsProps {
+ field: IndexPatternField;
+ indexPattern: IndexPattern;
+ details: FieldDetails;
+ onAddFilter: (field: IndexPatternField | string, value: string, type: '+' | '-') => void;
+}
+
+export function DiscoverFieldDetails({
+ field,
+ indexPattern,
+ details,
+ onAddFilter,
+}: DiscoverFieldDetailsProps) {
+ const warnings = getWarnings(field);
+
+ return (
+ );
- return comp;
+ return mountWithIntl( );
}
function findButtonGroup(component: ReactWrapper, id: string) {
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field_search.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field_search.tsx
similarity index 99%
rename from src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field_search.tsx
rename to src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field_search.tsx
index 2910ff2825fe..57f69693cb54 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field_search.tsx
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field_search.tsx
@@ -165,7 +165,7 @@ export function DiscoverFieldSearch({ onChange, value, types }: Props) {
}
isSelected={activeFiltersCount > 0}
quantity={activeFiltersCount}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_index_pattern.test.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_index_pattern.test.tsx
similarity index 100%
rename from src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_index_pattern.test.tsx
rename to src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_index_pattern.test.tsx
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_index_pattern.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_index_pattern.tsx
similarity index 94%
rename from src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_index_pattern.tsx
rename to src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_index_pattern.tsx
index fd2f96ca83a2..3b01d5e7a9e6 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_index_pattern.tsx
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_index_pattern.tsx
@@ -17,7 +17,7 @@
* under the License.
*/
import React, { useState, useEffect } from 'react';
-import { SavedObject } from 'kibana/server';
+import { SavedObject } from 'kibana/public';
import { IIndexPattern, IndexPatternAttributes } from 'src/plugins/data/public';
import { I18nProvider } from '@kbn/i18n/react';
@@ -65,14 +65,14 @@ export function DiscoverIndexPattern({
}
return (
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
- - - -
-
-
-
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/lib/visualize_url_utils.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/lib/visualize_url_utils.ts
deleted file mode 100644
index 21e8e9f5e39a..000000000000
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/lib/visualize_url_utils.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import uuid from 'uuid/v4';
-// @ts-ignore
-import rison from 'rison-node';
-import {
- IFieldType,
- IIndexPattern,
- KBN_FIELD_TYPES,
-} from '../../../../../../../../../plugins/data/public';
-import { AppState } from '../../../angular/context_state';
-import { getServices } from '../../../../kibana_services';
-
-function getMapsAppBaseUrl() {
- const mapsAppVisAlias = getServices()
- .visualizations.getAliases()
- .find(({ name }) => {
- return name === 'maps';
- });
- return mapsAppVisAlias ? mapsAppVisAlias.aliasUrl : null;
-}
-
-export function isMapsAppRegistered() {
- return getServices()
- .visualizations.getAliases()
- .some(({ name }) => {
- return name === 'maps';
- });
-}
-
-export function isFieldVisualizable(field: IFieldType) {
- if (
- (field.type === KBN_FIELD_TYPES.GEO_POINT || field.type === KBN_FIELD_TYPES.GEO_SHAPE) &&
- isMapsAppRegistered()
- ) {
- return true;
- }
- return field.visualizable;
-}
-
-export function getMapsAppUrl(
- field: IFieldType,
- indexPattern: IIndexPattern,
- appState: AppState,
- columns: string[]
-) {
- const mapAppParams = new URLSearchParams();
-
- // Copy global state
- const locationSplit = window.location.href.split('discover?');
- if (locationSplit.length > 1) {
- const discoverParams = new URLSearchParams(locationSplit[1]);
- const globalStateUrlValue = discoverParams.get('_g');
- if (globalStateUrlValue) {
- mapAppParams.set('_g', globalStateUrlValue);
- }
- }
-
- // Copy filters and query in app state
- const mapsAppState: any = {
- filters: appState.filters || [],
- };
- if (appState.query) {
- mapsAppState.query = appState.query;
- }
- // @ts-ignore
- mapAppParams.set('_a', rison.encode(mapsAppState));
-
- // create initial layer descriptor
- const hasColumns = columns && columns.length && columns[0] !== '_source';
- const supportsClustering = field.aggregatable;
- mapAppParams.set(
- 'initialLayers',
- // @ts-ignore
- rison.encode_array([
- {
- id: uuid(),
- label: indexPattern.title,
- sourceDescriptor: {
- id: uuid(),
- type: 'ES_SEARCH',
- geoField: field.name,
- tooltipProperties: hasColumns ? columns : [],
- indexPatternId: indexPattern.id,
- scalingType: supportsClustering ? 'CLUSTERS' : 'LIMIT',
- },
- visible: true,
- type: supportsClustering ? 'BLENDED_VECTOR' : 'VECTOR',
- },
- ])
- );
-
- return getServices().addBasePath(`${getMapsAppBaseUrl()}?${mapAppParams.toString()}`);
-}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/__snapshots__/discover_index_pattern.test.tsx.snap b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/__snapshots__/discover_index_pattern.test.tsx.snap
similarity index 100%
rename from src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/__snapshots__/discover_index_pattern.test.tsx.snap
rename to src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/__snapshots__/discover_index_pattern.test.tsx.snap
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/_index.scss b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/_index.scss
new file mode 100644
index 000000000000..17b0a6c9cfe4
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/_index.scss
@@ -0,0 +1 @@
+@import './_sidebar';
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/_sidebar.scss b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/_sidebar.scss
new file mode 100644
index 000000000000..fe04d42d614f
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/_sidebar.scss
@@ -0,0 +1,155 @@
+.dscSidebar__container {
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+ background-color: transparent;
+ border-right-color: transparent;
+ border-bottom-color: transparent;
+}
+
+.dscIndexPattern__container {
+ display: flex;
+ align-items: center;
+ height: $euiSize * 3;
+ margin-top: -$euiSizeS;
+}
+
+.dscIndexPattern__triggerButton {
+ @include euiTitle('xs');
+ line-height: $euiSizeXXL;
+}
+
+.dscFieldList {
+ list-style: none;
+ margin-bottom: 0;
+}
+
+.dscFieldList--selected,
+.dscFieldList--unpopular,
+.dscFieldList--popular {
+ padding-left: $euiSizeS;
+ padding-right: $euiSizeS;
+}
+
+.dscFieldListHeader {
+ padding: $euiSizeS $euiSizeS 0 $euiSizeS;
+ background-color: lightOrDarkTheme(tint($euiColorPrimary, 90%), $euiColorLightShade);
+}
+
+.dscFieldList--popular {
+ background-color: lightOrDarkTheme(tint($euiColorPrimary, 90%), $euiColorLightShade);
+}
+
+.dscFieldChooser {
+ padding-left: $euiSizeS !important;
+ padding-right: $euiSizeS !important;
+}
+
+.dscFieldChooser__toggle {
+ color: $euiColorMediumShade;
+ margin-left: $euiSizeS !important;
+}
+
+.dscSidebarItem {
+ border-top: 1px solid transparent;
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0 2px;
+ cursor: pointer;
+ font-size: $euiFontSizeXS;
+ border-top: solid 1px transparent;
+ border-bottom: solid 1px transparent;
+ line-height: normal;
+
+ &:hover,
+ &:focus {
+ .dscSidebarItem__action {
+ opacity: 1;
+ }
+ }
+}
+
+.dscSidebarItem--active {
+ border-top: 1px solid $euiColorLightShade;
+ background: shade($euiColorLightestShade, 5%);
+ color: $euiColorFullShade;
+ .euiText {
+ font-weight: bold;
+ }
+}
+
+.dscSidebarField {
+ padding: $euiSizeXS 0;
+ display: flex;
+ align-items: flex-start;
+ max-width: 100%;
+ margin: 0;
+ width: 100%;
+ border: none;
+ border-radius: 0;
+ text-align: left;
+}
+
+.dscSidebarField__name {
+ margin-left: $euiSizeS;
+ flex-grow: 1;
+}
+
+.dscSidebarField__fieldIcon {
+ margin-top: $euiSizeXS / 2;
+ margin-right: $euiSizeXS / 2;
+}
+
+/**
+ * 1. Only visually hide the action, so that it's still accessible to screen readers.
+ * 2. When tabbed to, this element needs to be visible for keyboard accessibility.
+ */
+.dscSidebarItem__action {
+ opacity: 0; /* 1 */
+
+ &:focus {
+ opacity: 1; /* 2 */
+ }
+ font-size: 12px;
+ padding: 2px 6px !important;
+ height: 22px !important;
+ min-width: auto !important;
+ .euiButton__content {
+ padding: 0 4px;
+ }
+}
+
+/*
+ Fixes EUI known issue https://github.com/elastic/eui/issues/1749
+*/
+.dscProgressBarTooltip__anchor {
+ display: block;
+}
+
+
+.dscFieldSearch {
+ padding: $euiSizeS;
+}
+
+.dscFieldSearch__toggleButton {
+ width: calc(100% - #{$euiSizeS});
+ color: $euiColorPrimary;
+ padding-left: $euiSizeXS;
+ margin-left: $euiSizeXS;
+}
+
+.dscFieldSearch__filterWrapper {
+ flex-grow: 0;
+}
+
+.dscFieldSearch__formWrapper {
+ padding: $euiSizeM;
+}
+
+.dscFieldDetails {
+ padding: $euiSizeS;
+ background-color: $euiColorLightestShade;
+ color: $euiTextColor;
+ margin-bottom: $euiSizeS;
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/change_indexpattern.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/change_indexpattern.tsx
similarity index 100%
rename from src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/change_indexpattern.tsx
rename to src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/change_indexpattern.tsx
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field.test.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field.test.tsx
new file mode 100644
index 000000000000..9a6bd65813d1
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field.test.tsx
@@ -0,0 +1,111 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from 'react';
+// @ts-ignore
+import { findTestSubject } from '@elastic/eui/lib/test';
+// @ts-ignore
+import StubIndexPattern from 'test_utils/stub_index_pattern';
+// @ts-ignore
+import stubbedLogstashFields from 'fixtures/logstash_fields';
+import { mountWithIntl } from 'test_utils/enzyme_helpers';
+import { DiscoverField } from './discover_field';
+import { coreMock } from '../../../../../../../../core/public/mocks';
+import { IndexPatternField } from '../../../../../../../../plugins/data/public';
+
+jest.mock('../../../kibana_services', () => ({
+ getServices: () => ({
+ history: {
+ location: {
+ search: '',
+ },
+ },
+ capabilities: {
+ visualize: {
+ show: true,
+ },
+ },
+ uiSettings: {
+ get: (key: string) => {
+ if (key === 'fields:popularLimit') {
+ return 5;
+ } else if (key === 'shortDots:enable') {
+ return false;
+ }
+ },
+ },
+ }),
+}));
+
+function getComponent(selected = false, showDetails = false, useShortDots = false) {
+ const indexPattern = new StubIndexPattern(
+ 'logstash-*',
+ (cfg: any) => cfg,
+ 'time',
+ stubbedLogstashFields(),
+ coreMock.createStart()
+ );
+
+ const field = {
+ name: 'bytes',
+ type: 'number',
+ esTypes: ['long'],
+ count: 10,
+ scripted: false,
+ searchable: true,
+ aggregatable: true,
+ readFromDocValues: true,
+ format: null,
+ routes: {},
+ $$spec: {},
+ } as IndexPatternField;
+
+ const props = {
+ indexPattern,
+ field,
+ getDetails: jest.fn(),
+ onAddFilter: jest.fn(),
+ onAddField: jest.fn(),
+ onRemoveField: jest.fn(),
+ onShowDetails: jest.fn(),
+ showDetails,
+ selected,
+ useShortDots,
+ };
+ const comp = mountWithIntl(
-
-
-
-
-
- ( )
-
-
-- - - - {{::field.details.exists}} - - - {{::field.details.exists}} - - / {{::field.details.total}} - - -
- - - -{{field.details.error}}
-
-
-
-
-
-
-
-
-
-
- {{::bucket.display}}
-
-
-
-
-
-
-
-
-
- onShowDetails(!showDetails, field)}
+ onKeyPress={() => onShowDetails(!showDetails, field)}
+ data-test-subj={`field-${field.name}-showDetails`}
+ >
+
+
+
+
+
+
+ {useShortDots ? shortenDottedString(field.name) : field.displayName}
+
+
+
+
+ {field.name !== '_source' && !selected && (
+ ) => {
+ ev.preventDefault();
+ ev.stopPropagation();
+ toggleDisplay(field);
+ }}
+ data-test-subj={`fieldToggle-${field.name}`}
+ arial-label={addLabelAria}
+ >
+ {addLabel}
+
+ )}
+ {field.name !== '_source' && selected && (
+ ) => {
+ ev.preventDefault();
+ ev.stopPropagation();
+ toggleDisplay(field);
+ }}
+ data-test-subj={`fieldToggle-${field.name}`}
+ arial-label={removeLabelAria}
+ >
+ {removeLabel}
+
+ )}
+
+
+ {showDetails && (
+
+ onAddFilter(field, bucket.value, '+')}
+ aria-label={addLabel}
+ data-test-subj={`plus-${field.name}-${bucket.value}`}
+ style={{
+ minHeight: 'auto',
+ minWidth: 'auto',
+ paddingRight: 2,
+ paddingLeft: 2,
+ paddingTop: 0,
+ paddingBottom: 0,
+ }}
+ />
+ onAddFilter(field, bucket.value, '-')}
+ aria-label={removeLabel}
+ data-test-subj={`minus-${field.name}-${bucket.value}`}
+ style={{
+ minHeight: 'auto',
+ minWidth: 'auto',
+ paddingTop: 0,
+ paddingBottom: 0,
+ paddingRight: 2,
+ paddingLeft: 2,
+ }}
+ />
+
+
+ {!details.error && (
+
+ {' '}
+ {!indexPattern.metaFields.includes(field.name) && !field.scripted ? (
+ onAddFilter('_exists_', field.name, '+')}>
+ {details.exists}
+
+ ) : (
+ {details.exists}
+ )}{' '}
+ / {details.total}{' '}
+
+
+ )}
+ {details.error && {details.error} }
+ {!details.error && (
+
+
+
+ {warnings.length > 0 && (
+
+ )}
+
+ >
+ )}
+
+ );
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field_search.test.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field_search.test.tsx
similarity index 98%
rename from src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field_search.test.tsx
rename to src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field_search.test.tsx
index 5054f7b4bdad..654df5bfa9ee 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field_search.test.tsx
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_field_search.test.tsx
@@ -34,8 +34,7 @@ describe('DiscoverFieldSearch', () => {
function mountComponent(props?: Props) {
const compProps = props || defaultProps;
- const comp = mountWithIntl(
+ {details.buckets.map((bucket: Bucket, idx: number) => (
+
+ ))}
+
+ )}
+
+ {details.visualizeUrl && (
+ <>
+
+
({
+ getServices: () => ({
+ history: {
+ location: {
+ search: '',
+ },
+ },
+ capabilities: {
+ visualize: {
+ show: true,
+ },
+ },
+ uiSettings: {
+ get: (key: string) => {
+ if (key === 'fields:popularLimit') {
+ return 5;
+ } else if (key === 'shortDots:enable') {
+ return false;
+ }
+ },
+ },
+ }),
+}));
+
+function getCompProps() {
+ const indexPattern = new StubIndexPattern(
+ 'logstash-*',
+ (cfg: any) => cfg,
+ 'time',
+ stubbedLogstashFields(),
+ coreMock.createStart()
+ );
+
+ const hits = _.each(_.cloneDeep(realHits), indexPattern.flattenHit) as Array<
+ Record
+ >;
+
+ const indexPatternList = [
+ { id: '0', attributes: { title: 'b' } } as SavedObject,
+ { id: '1', attributes: { title: 'a' } } as SavedObject,
+ { id: '2', attributes: { title: 'c' } } as SavedObject,
+ ];
+
+ const fieldCounts: Record = {};
+
+ for (const hit of hits) {
+ for (const key of Object.keys(indexPattern.flattenHit(hit))) {
+ fieldCounts[key] = (fieldCounts[key] || 0) + 1;
+ }
+ }
+ return {
+ columns: ['extension'],
+ fieldCounts,
+ hits,
+ indexPatternList,
+ onAddFilter: jest.fn(),
+ onAddField: jest.fn(),
+ onRemoveField: jest.fn(),
+ selectedIndexPattern: indexPattern,
+ setIndexPattern: jest.fn(),
+ state: {},
+ };
+}
+
+describe('discover sidebar', function() {
+ let props: DiscoverSidebarProps;
+ let comp: ReactWrapper;
+
+ beforeAll(() => {
+ props = getCompProps();
+ comp = mountWithIntl( );
+ });
+
+ it('should have Selected Fields and Available Fields with Popular Fields sections', function() {
+ const popular = findTestSubject(comp, 'fieldList-popular');
+ const selected = findTestSubject(comp, 'fieldList-selected');
+ const unpopular = findTestSubject(comp, 'fieldList-unpopular');
+ expect(popular.children().length).toBe(1);
+ expect(unpopular.children().length).toBe(7);
+ expect(selected.children().length).toBe(1);
+ });
+ it('should allow selecting fields', function() {
+ findTestSubject(comp, 'fieldToggle-bytes').simulate('click');
+ expect(props.onAddField).toHaveBeenCalledWith('bytes');
+ });
+ it('should allow deselecting fields', function() {
+ findTestSubject(comp, 'fieldToggle-extension').simulate('click');
+ expect(props.onRemoveField).toHaveBeenCalledWith('extension');
+ });
+ it('should allow adding filters', function() {
+ findTestSubject(comp, 'field-extension-showDetails').simulate('click');
+ findTestSubject(comp, 'plus-extension-gif').simulate('click');
+ expect(props.onAddFilter).toHaveBeenCalled();
+ });
+});
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_sidebar.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_sidebar.tsx
new file mode 100644
index 000000000000..5984df9c76e6
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_sidebar.tsx
@@ -0,0 +1,326 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React, { useCallback, useEffect, useState, useMemo } from 'react';
+import { i18n } from '@kbn/i18n';
+import { EuiButtonIcon, EuiTitle } from '@elastic/eui';
+import { sortBy } from 'lodash';
+import { FormattedMessage } from '@kbn/i18n/react';
+import { DiscoverField } from './discover_field';
+import { DiscoverIndexPattern } from './discover_index_pattern';
+import { DiscoverFieldSearch } from './discover_field_search';
+import { IndexPatternAttributes } from '../../../../../../../../plugins/data/common';
+import { SavedObject } from '../../../../../../../../core/types';
+import { groupFields } from './lib/group_fields';
+import {
+ IndexPatternFieldList,
+ IndexPatternField,
+ IndexPattern,
+} from '../../../../../../../../plugins/data/public';
+import { AppState } from '../../angular/discover_state';
+import { getDetails } from './lib/get_details';
+import { getDefaultFieldFilter, setFieldFilterProp } from './lib/field_filter';
+import { getIndexPatternFieldList } from './lib/get_index_pattern_field_list';
+import { getServices } from '../../../kibana_services';
+
+export interface DiscoverSidebarProps {
+ /**
+ * the selected columns displayed in the doc table in discover
+ */
+ columns: string[];
+ /**
+ * a statistics of the distribution of fields in the given hits
+ */
+ fieldCounts: Record;
+ /**
+ * hits fetched from ES, displayed in the doc table
+ */
+ hits: Array>;
+ /**
+ * List of available index patterns
+ */
+ indexPatternList: Array>;
+ /**
+ * Callback function when selecting a field
+ */
+ onAddField: (fieldName: string) => void;
+ /**
+ * Callback function when adding a filter from sidebar
+ */
+ onAddFilter: (field: IndexPatternField | string, value: string, type: '+' | '-') => void;
+ /**
+ * Callback function when removing a field
+ * @param fieldName
+ */
+ onRemoveField: (fieldName: string) => void;
+ /**
+ * Currently selected index pattern
+ */
+ selectedIndexPattern: IndexPattern;
+ /**
+ * Callback function to select another index pattern
+ */
+ setIndexPattern: (id: string) => void;
+ /**
+ * Current app state, used for generating a link to visualize
+ */
+ state: AppState;
+}
+
+export function DiscoverSidebar({
+ columns,
+ fieldCounts,
+ hits,
+ indexPatternList,
+ onAddField,
+ onAddFilter,
+ onRemoveField,
+ selectedIndexPattern,
+ setIndexPattern,
+ state,
+}: DiscoverSidebarProps) {
+ const [openFieldMap, setOpenFieldMap] = useState(new Map());
+ const [showFields, setShowFields] = useState(false);
+ const [fields, setFields] = useState(null);
+ const [fieldFilterState, setFieldFilterState] = useState(getDefaultFieldFilter());
+ const services = getServices();
+
+ useEffect(() => {
+ const newFields = getIndexPatternFieldList(selectedIndexPattern, fieldCounts);
+ setFields(newFields);
+ }, [selectedIndexPattern, fieldCounts, hits]);
+
+ const onShowDetails = useCallback(
+ (show: boolean, field: IndexPatternField) => {
+ if (!show) {
+ setOpenFieldMap(new Map(openFieldMap.set(field.name, false)));
+ } else {
+ setOpenFieldMap(new Map(openFieldMap.set(field.name, true)));
+ selectedIndexPattern.popularizeField(field.name, 1);
+ }
+ },
+ [openFieldMap, selectedIndexPattern]
+ );
+ const onChangeFieldSearch = useCallback(
+ (field: string, value: string | boolean | undefined) => {
+ const newState = setFieldFilterProp(fieldFilterState, field, value);
+ setFieldFilterState(newState);
+ },
+ [fieldFilterState]
+ );
+
+ const getDetailsByField = useCallback(
+ (ipField: IndexPatternField) =>
+ getDetails(ipField, selectedIndexPattern, state, columns, hits, services),
+ [selectedIndexPattern, state, columns, hits, services]
+ );
+
+ const popularLimit = services.uiSettings.get('fields:popularLimit');
+ const useShortDots = services.uiSettings.get('shortDots:enable');
+
+ const {
+ selected: selectedFields,
+ popular: popularFields,
+ unpopular: unpopularFields,
+ } = useMemo(() => groupFields(fields, columns, popularLimit, fieldCounts, fieldFilterState), [
+ fields,
+ columns,
+ popularLimit,
+ fieldCounts,
+ fieldFilterState,
+ ]);
+
+ const fieldTypes = useMemo(() => {
+ const result = ['any'];
+ if (Array.isArray(fields)) {
+ for (const field of fields) {
+ if (result.indexOf(field.type) === -1) {
+ result.push(field.type);
+ }
+ }
+ }
+ return result;
+ }, [fields]);
+
+ if (!selectedIndexPattern || !fields) {
+ return null;
+ }
+
+ return (
+
+ o.attributes.title)}
+ />
+
+ );
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_index_pattern_directive.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_sidebar_directive.ts
similarity index 61%
rename from src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_index_pattern_directive.tsx
rename to src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_sidebar_directive.ts
index d6527b0d7bee..9dcb459f8361 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_index_pattern_directive.tsx
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_sidebar_directive.ts
@@ -16,25 +16,20 @@
* specific language governing permissions and limitations
* under the License.
*/
-import React from 'react';
import { wrapInI18nContext } from '../../../kibana_services';
-import { DiscoverIndexPattern, DiscoverIndexPatternProps } from './discover_index_pattern';
+import { DiscoverSidebar } from './discover_sidebar';
-/**
- * At initial rendering the angular directive the selectedIndexPattern prop is undefined
- * This wrapper catches this, had to be introduced to satisfy eslint
- */
-export function DiscoverIndexPatternWrapper(props: DiscoverIndexPatternProps) {
- if (!props.selectedIndexPattern || !Array.isArray(props.indexPatternList)) {
- return null;
- }
- return ;
-}
-
-export function createIndexPatternSelectDirective(reactDirective: any) {
- return reactDirective(wrapInI18nContext(DiscoverIndexPatternWrapper), [
+export function createDiscoverSidebarDirective(reactDirective: any) {
+ return reactDirective(wrapInI18nContext(DiscoverSidebar), [
+ ['columns', { watchDepth: 'reference' }],
+ ['fieldCounts', { watchDepth: 'reference' }],
+ ['hits', { watchDepth: 'reference' }],
['indexPatternList', { watchDepth: 'reference' }],
+ ['onAddField', { watchDepth: 'reference' }],
+ ['onAddFilter', { watchDepth: 'reference' }],
+ ['onRemoveField', { watchDepth: 'reference' }],
['selectedIndexPattern', { watchDepth: 'reference' }],
['setIndexPattern', { watchDepth: 'reference' }],
+ ['state', { watchDepth: 'reference' }],
]);
}
diff --git a/src/legacy/core_plugins/embeddable_api/public/np_ready/public/lib/test_samples/index.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/index.ts
similarity index 85%
rename from src/legacy/core_plugins/embeddable_api/public/np_ready/public/lib/test_samples/index.ts
rename to src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/index.ts
index 4f0537aff5dc..1b837840b52f 100644
--- a/src/legacy/core_plugins/embeddable_api/public/np_ready/public/lib/test_samples/index.ts
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/index.ts
@@ -17,5 +17,5 @@
* under the License.
*/
-// eslint-disable-next-line
-export * from '../../../../../../../../plugins/embeddable/public/lib/test_samples';
+export { DiscoverSidebar } from './discover_sidebar';
+export { createDiscoverSidebarDirective } from './discover_sidebar_directive';
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/lib/field_calculator.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/field_calculator.js
similarity index 100%
rename from src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/lib/field_calculator.js
rename to src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/field_calculator.js
diff --git a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_calculator.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/field_calculator.test.ts
similarity index 64%
rename from src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_calculator.js
rename to src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/field_calculator.test.ts
index f302d684135f..98763937e888 100644
--- a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_calculator.js
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/field_calculator.test.ts
@@ -18,25 +18,29 @@
*/
import _ from 'lodash';
-import { pluginInstance } from 'plugins/kibana/discover/legacy';
-import ngMock from 'ng_mock';
-import { fieldCalculator } from '../../np_ready/components/field_chooser/lib/field_calculator';
-import expect from '@kbn/expect';
-import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
-
-// Load the kibana app dependencies.
-
-let indexPattern;
+// @ts-ignore
+import realHits from 'fixtures/real_hits.js';
+// @ts-ignore
+import StubIndexPattern from 'test_utils/stub_index_pattern';
+// @ts-ignore
+import stubbedLogstashFields from 'fixtures/logstash_fields';
+import { coreMock } from '../../../../../../../../../core/public/mocks';
+import { IndexPattern } from '../../../../../../../../../plugins/data/public';
+// @ts-ignore
+import { fieldCalculator } from './field_calculator';
+
+let indexPattern: IndexPattern;
describe('fieldCalculator', function() {
- beforeEach(() => pluginInstance.initializeInnerAngular());
- beforeEach(ngMock.module('app/discover'));
- beforeEach(
- ngMock.inject(function(Private) {
- indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
- })
- );
-
+ beforeEach(function() {
+ indexPattern = new StubIndexPattern(
+ 'logstash-*',
+ (cfg: any) => cfg,
+ 'time',
+ stubbedLogstashFields(),
+ coreMock.createStart()
+ );
+ });
it('should have a _countMissing that counts nulls & undefineds in an array', function() {
const values = [
['foo', 'bar'],
@@ -52,13 +56,13 @@ describe('fieldCalculator', function() {
'foo',
undefined,
];
- expect(fieldCalculator._countMissing(values)).to.be(5);
+ expect(fieldCalculator._countMissing(values)).toBe(5);
});
describe('_groupValues', function() {
- let groups;
- let params;
- let values;
+ let groups: Record;
+ let params: any;
+ let values: any;
beforeEach(function() {
values = [
['foo', 'bar'],
@@ -79,36 +83,36 @@ describe('fieldCalculator', function() {
});
it('should have a _groupValues that counts values', function() {
- expect(groups).to.be.an(Object);
+ expect(groups).toBeInstanceOf(Object);
});
it('should throw an error if any value is a plain object', function() {
expect(function() {
fieldCalculator._groupValues([{}, true, false], params);
- }).to.throwError();
+ }).toThrowError();
});
it('should handle values with dots in them', function() {
values = ['0', '0.........', '0.......,.....'];
params = {};
groups = fieldCalculator._groupValues(values, params);
- expect(groups[values[0]].count).to.be(1);
- expect(groups[values[1]].count).to.be(1);
- expect(groups[values[2]].count).to.be(1);
+ expect(groups[values[0]].count).toBe(1);
+ expect(groups[values[1]].count).toBe(1);
+ expect(groups[values[2]].count).toBe(1);
});
it('should have a a key for value in the array when not grouping array terms', function() {
- expect(_.keys(groups).length).to.be(3);
- expect(groups.foo).to.be.a(Object);
- expect(groups.bar).to.be.a(Object);
- expect(groups.baz).to.be.a(Object);
+ expect(_.keys(groups).length).toBe(3);
+ expect(groups.foo).toBeInstanceOf(Object);
+ expect(groups.bar).toBeInstanceOf(Object);
+ expect(groups.baz).toBeInstanceOf(Object);
});
it('should count array terms independently', function() {
- expect(groups['foo,bar']).to.be(undefined);
- expect(groups.foo.count).to.be(5);
- expect(groups.bar.count).to.be(3);
- expect(groups.baz.count).to.be(1);
+ expect(groups['foo,bar']).toBe(undefined);
+ expect(groups.foo.count).toBe(5);
+ expect(groups.bar.count).toBe(3);
+ expect(groups.baz.count).toBe(1);
});
describe('grouped array terms', function() {
@@ -118,27 +122,27 @@ describe('fieldCalculator', function() {
});
it('should group array terms when passed params.grouped', function() {
- expect(_.keys(groups).length).to.be(4);
- expect(groups['foo,bar']).to.be.a(Object);
+ expect(_.keys(groups).length).toBe(4);
+ expect(groups['foo,bar']).toBeInstanceOf(Object);
});
it('should contain the original array as the value', function() {
- expect(groups['foo,bar'].value).to.eql(['foo', 'bar']);
+ expect(groups['foo,bar'].value).toEqual(['foo', 'bar']);
});
it('should count the pairs separately from the values they contain', function() {
- expect(groups['foo,bar'].count).to.be(2);
- expect(groups.foo.count).to.be(3);
- expect(groups.bar.count).to.be(1);
+ expect(groups['foo,bar'].count).toBe(2);
+ expect(groups.foo.count).toBe(3);
+ expect(groups.bar.count).toBe(1);
});
});
});
describe('getFieldValues', function() {
- let hits;
+ let hits: any;
beforeEach(function() {
- hits = _.each(require('fixtures/real_hits.js'), indexPattern.flattenHit);
+ hits = _.each(_.cloneDeep(realHits), indexPattern.flattenHit);
});
it('Should return an array of values for _source fields', function() {
@@ -146,32 +150,32 @@ describe('fieldCalculator', function() {
hits,
indexPattern.fields.getByName('extension')
);
- expect(extensions).to.be.an(Array);
+ expect(extensions).toBeInstanceOf(Array);
expect(
_.filter(extensions, function(v) {
return v === 'html';
}).length
- ).to.be(8);
- expect(_.uniq(_.clone(extensions)).sort()).to.eql(['gif', 'html', 'php', 'png']);
+ ).toBe(8);
+ expect(_.uniq(_.clone(extensions)).sort()).toEqual(['gif', 'html', 'php', 'png']);
});
it('Should return an array of values for core meta fields', function() {
const types = fieldCalculator.getFieldValues(hits, indexPattern.fields.getByName('_type'));
- expect(types).to.be.an(Array);
+ expect(types).toBeInstanceOf(Array);
expect(
_.filter(types, function(v) {
return v === 'apache';
}).length
- ).to.be(18);
- expect(_.uniq(_.clone(types)).sort()).to.eql(['apache', 'nginx']);
+ ).toBe(18);
+ expect(_.uniq(_.clone(types)).sort()).toEqual(['apache', 'nginx']);
});
});
describe('getFieldValueCounts', function() {
- let params;
+ let params: { hits: any; field: any; count: number };
beforeEach(function() {
params = {
- hits: require('fixtures/real_hits.js'),
+ hits: _.cloneDeep(realHits),
field: indexPattern.fields.getByName('extension'),
count: 3,
};
@@ -179,36 +183,36 @@ describe('fieldCalculator', function() {
it('counts the top 3 values', function() {
const extensions = fieldCalculator.getFieldValueCounts(params);
- expect(extensions).to.be.an(Object);
- expect(extensions.buckets).to.be.an(Array);
- expect(extensions.buckets.length).to.be(3);
- expect(_.pluck(extensions.buckets, 'value')).to.eql(['html', 'php', 'gif']);
- expect(extensions.error).to.be(undefined);
+ expect(extensions).toBeInstanceOf(Object);
+ expect(extensions.buckets).toBeInstanceOf(Array);
+ expect(extensions.buckets.length).toBe(3);
+ expect(_.pluck(extensions.buckets, 'value')).toEqual(['html', 'php', 'gif']);
+ expect(extensions.error).toBe(undefined);
});
it('fails to analyze geo and attachment types', function() {
params.field = indexPattern.fields.getByName('point');
- expect(fieldCalculator.getFieldValueCounts(params).error).to.not.be(undefined);
+ expect(fieldCalculator.getFieldValueCounts(params).error).not.toBe(undefined);
params.field = indexPattern.fields.getByName('area');
- expect(fieldCalculator.getFieldValueCounts(params).error).to.not.be(undefined);
+ expect(fieldCalculator.getFieldValueCounts(params).error).not.toBe(undefined);
params.field = indexPattern.fields.getByName('request_body');
- expect(fieldCalculator.getFieldValueCounts(params).error).to.not.be(undefined);
+ expect(fieldCalculator.getFieldValueCounts(params).error).not.toBe(undefined);
});
it('fails to analyze fields that are in the mapping, but not the hits', function() {
params.field = indexPattern.fields.getByName('ip');
- expect(fieldCalculator.getFieldValueCounts(params).error).to.not.be(undefined);
+ expect(fieldCalculator.getFieldValueCounts(params).error).not.toBe(undefined);
});
it('counts the total hits', function() {
- expect(fieldCalculator.getFieldValueCounts(params).total).to.be(params.hits.length);
+ expect(fieldCalculator.getFieldValueCounts(params).total).toBe(params.hits.length);
});
it('counts the hits the field exists in', function() {
params.field = indexPattern.fields.getByName('phpmemory');
- expect(fieldCalculator.getFieldValueCounts(params).exists).to.be(5);
+ expect(fieldCalculator.getFieldValueCounts(params).exists).toBe(5);
});
});
});
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/field_filter.test.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/field_filter.test.ts
new file mode 100644
index 000000000000..ca0fcfc84636
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/field_filter.test.ts
@@ -0,0 +1,96 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { getDefaultFieldFilter, setFieldFilterProp, isFieldFiltered } from './field_filter';
+import { IndexPatternField } from '../../../../../../../../../plugins/data/public';
+
+describe('field_filter', function() {
+ it('getDefaultFieldFilter should return default filter state', function() {
+ expect(getDefaultFieldFilter()).toMatchInlineSnapshot(`
+ Object {
+ "aggregatable": null,
+ "missing": true,
+ "name": "",
+ "searchable": null,
+ "type": "any",
+ }
+ `);
+ });
+ it('setFieldFilterProp should return allow filter changes', function() {
+ const state = getDefaultFieldFilter();
+ const targetState = {
+ aggregatable: true,
+ missing: true,
+ name: 'test',
+ searchable: true,
+ type: 'string',
+ };
+ const actualState = Object.entries(targetState).reduce((acc, kv) => {
+ return setFieldFilterProp(acc, kv[0], kv[1]);
+ }, state);
+ expect(actualState).toMatchInlineSnapshot(`
+ Object {
+ "aggregatable": true,
+ "missing": true,
+ "name": "test",
+ "searchable": true,
+ "type": "string",
+ }
+ `);
+ });
+ it('filters a given list', () => {
+ const defaultState = getDefaultFieldFilter();
+ const fieldList = [
+ {
+ name: 'bytes',
+ type: 'number',
+ esTypes: ['long'],
+ count: 10,
+ scripted: false,
+ searchable: false,
+ aggregatable: false,
+ },
+ {
+ name: 'extension',
+ type: 'string',
+ esTypes: ['text'],
+ count: 10,
+ scripted: true,
+ searchable: true,
+ aggregatable: true,
+ },
+ ] as IndexPatternField[];
+
+ [
+ { filter: {}, result: ['bytes', 'extension'] },
+ { filter: { name: 'by' }, result: ['bytes'] },
+ { filter: { aggregatable: true }, result: ['extension'] },
+ { filter: { aggregatable: true, searchable: false }, result: [] },
+ { filter: { type: 'string' }, result: ['extension'] },
+ ].forEach(test => {
+ const filtered = fieldList
+ .filter(field =>
+ isFieldFiltered(field, { ...defaultState, ...test.filter }, { bytes: 1, extension: 1 })
+ )
+ .map(field => field.name);
+
+ expect(filtered).toEqual(test.result);
+ });
+ });
+});
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/field_filter.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/field_filter.ts
new file mode 100644
index 000000000000..ed7ad1a43fa8
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/field_filter.ts
@@ -0,0 +1,78 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { IndexPatternField } from '../../../../../../../../../plugins/data/public';
+
+export interface FieldFilterState {
+ missing: boolean;
+ type: string;
+ name: string;
+ aggregatable: null | boolean;
+ searchable: null | boolean;
+}
+
+export function getDefaultFieldFilter(): FieldFilterState {
+ return {
+ missing: true,
+ type: 'any',
+ name: '',
+ aggregatable: null,
+ searchable: null,
+ };
+}
+
+export function setFieldFilterProp(
+ state: FieldFilterState,
+ name: string,
+ value: string | boolean | null | undefined
+): FieldFilterState {
+ const newState = { ...state };
+ if (name === 'missing') {
+ newState.missing = Boolean(value);
+ } else if (name === 'aggregatable') {
+ newState.aggregatable = typeof value !== 'boolean' ? null : value;
+ } else if (name === 'searchable') {
+ newState.searchable = typeof value !== 'boolean' ? null : value;
+ } else if (name === 'name') {
+ newState.name = String(value);
+ } else if (name === 'type') {
+ newState.type = String(value);
+ }
+ return newState;
+}
+
+export function isFieldFiltered(
+ field: IndexPatternField,
+ filterState: FieldFilterState,
+ fieldCounts: Record
+): boolean {
+ const matchFilter = filterState.type === 'any' || field.type === filterState.type;
+ const isAggregatable =
+ filterState.aggregatable === null || field.aggregatable === filterState.aggregatable;
+ const isSearchable =
+ filterState.searchable === null || field.searchable === filterState.searchable;
+ const scriptedOrMissing =
+ !filterState.missing ||
+ field.type === '_source' ||
+ field.scripted ||
+ fieldCounts[field.name] > 0;
+ const matchName = !filterState.name || field.name.indexOf(filterState.name) !== -1;
+
+ return matchFilter && isAggregatable && isSearchable && scriptedOrMissing && matchName;
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/get_details.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/get_details.ts
new file mode 100644
index 000000000000..9999b108c5cc
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/get_details.ts
@@ -0,0 +1,52 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { getVisualizeUrl, isFieldVisualizable } from './visualize_url_utils';
+import { AppState } from '../../../angular/discover_state';
+// @ts-ignore
+import { fieldCalculator } from './field_calculator';
+import { IndexPatternField, IndexPattern } from '../../../../../../../../../plugins/data/public';
+import { DiscoverServices } from '../../../../build_services';
+
+export function getDetails(
+ field: IndexPatternField,
+ indexPattern: IndexPattern,
+ state: AppState,
+ columns: string[],
+ hits: Array>,
+ services: DiscoverServices
+) {
+ const details = {
+ visualizeUrl:
+ services.capabilities.visualize.show && isFieldVisualizable(field, services.visualizations)
+ ? getVisualizeUrl(field, indexPattern, state, columns, services)
+ : null,
+ ...fieldCalculator.getFieldValueCounts({
+ hits,
+ field,
+ count: 5,
+ grouped: false,
+ }),
+ };
+ if (details.buckets) {
+ for (const bucket of details.buckets) {
+ bucket.display = field.format.convert(bucket.value);
+ }
+ }
+ return details;
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/get_field_type_name.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/get_field_type_name.ts
new file mode 100644
index 000000000000..0cf428ee48b9
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/get_field_type_name.ts
@@ -0,0 +1,73 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { i18n } from '@kbn/i18n';
+
+export function getFieldTypeName(type: string) {
+ switch (type) {
+ case 'boolean':
+ return i18n.translate('kbn.discover.fieldNameIcons.booleanAriaLabel', {
+ defaultMessage: 'Boolean field',
+ });
+ case 'conflict':
+ return i18n.translate('kbn.discover.fieldNameIcons.conflictFieldAriaLabel', {
+ defaultMessage: 'Conflicting field',
+ });
+ case 'date':
+ return i18n.translate('kbn.discover.fieldNameIcons.dateFieldAriaLabel', {
+ defaultMessage: 'Date field',
+ });
+ case 'geo_point':
+ return i18n.translate('kbn.discover.fieldNameIcons.geoPointFieldAriaLabel', {
+ defaultMessage: 'Geo point field',
+ });
+ case 'geo_shape':
+ return i18n.translate('kbn.discover.fieldNameIcons.geoShapeFieldAriaLabel', {
+ defaultMessage: 'Geo shape field',
+ });
+ case 'ip':
+ return i18n.translate('kbn.discover.fieldNameIcons.ipAddressFieldAriaLabel', {
+ defaultMessage: 'IP address field',
+ });
+ case 'murmur3':
+ return i18n.translate('kbn.discover.fieldNameIcons.murmur3FieldAriaLabel', {
+ defaultMessage: 'Murmur3 field',
+ });
+ case 'number':
+ return i18n.translate('kbn.discover.fieldNameIcons.numberFieldAriaLabel', {
+ defaultMessage: 'Number field',
+ });
+ case 'source':
+ // Note that this type is currently not provided, type for _source is undefined
+ return i18n.translate('kbn.discover.fieldNameIcons.sourceFieldAriaLabel', {
+ defaultMessage: 'Source field',
+ });
+ case 'string':
+ return i18n.translate('kbn.discover.fieldNameIcons.stringFieldAriaLabel', {
+ defaultMessage: 'String field',
+ });
+ case 'nested':
+ return i18n.translate('kbn.discover.fieldNameIcons.nestedFieldAriaLabel', {
+ defaultMessage: 'Nested field',
+ });
+ default:
+ return i18n.translate('kbn.discover.fieldNameIcons.unknownFieldAriaLabel', {
+ defaultMessage: 'Unknown field',
+ });
+ }
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/get_index_pattern_field_list.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/get_index_pattern_field_list.ts
new file mode 100644
index 000000000000..1b906501c6fe
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/get_index_pattern_field_list.ts
@@ -0,0 +1,44 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { difference, map } from 'lodash';
+import {
+ IndexPatternFieldList,
+ IndexPattern,
+ IndexPatternField,
+} from '../../../../../../../../../plugins/data/public';
+
+export function getIndexPatternFieldList(
+ indexPattern: IndexPattern,
+ fieldCounts: Record
+): IndexPatternFieldList {
+ if (!indexPattern || !fieldCounts) return new IndexPatternFieldList(indexPattern, []);
+
+ const fieldSpecs = indexPattern.fields.slice(0);
+ const fieldNamesInDocs = Object.keys(fieldCounts);
+ const fieldNamesInIndexPattern = map(indexPattern.fields, 'name');
+
+ difference(fieldNamesInDocs, fieldNamesInIndexPattern).forEach(unknownFieldName => {
+ fieldSpecs.push({
+ name: String(unknownFieldName),
+ type: 'unknown',
+ } as IndexPatternField);
+ });
+
+ return new IndexPatternFieldList(indexPattern, fieldSpecs);
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/get_warnings.ts
similarity index 55%
rename from src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name.js
rename to src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/get_warnings.ts
index 47e50f3cc3d4..51d18c03888a 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name.js
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/get_warnings.ts
@@ -16,20 +16,28 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { FieldName } from '../../../../../../../../plugins/discover/public';
-import { getServices, wrapInI18nContext } from '../../../kibana_services';
+import { i18n } from '@kbn/i18n';
+import { IndexPatternField } from '../../../../../../../../../plugins/data/public';
-export function FieldNameDirectiveProvider(reactDirective) {
- return reactDirective(
- wrapInI18nContext(FieldName),
- [
- ['field', { watchDepth: 'collection' }],
- ['fieldName', { watchDepth: 'reference' }],
- ['fieldType', { watchDepth: 'reference' }],
- ],
- { restrict: 'AE' },
- {
- useShortDots: getServices().uiSettings.get('shortDots:enable'),
- }
- );
+export function getWarnings(field: IndexPatternField) {
+ let warnings = [];
+
+ if (field.scripted) {
+ warnings.push(
+ i18n.translate(
+ 'kbn.discover.fieldChooser.discoverField.scriptedFieldsTakeLongExecuteDescription',
+ {
+ defaultMessage: 'Scripted fields can take a long time to execute.',
+ }
+ )
+ );
+ }
+
+ if (warnings.length > 1) {
+ warnings = warnings.map(function(warning, i) {
+ return (i > 0 ? '\n' : '') + (i + 1) + ' - ' + warning;
+ });
+ }
+
+ return warnings;
}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/group_fields.test.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/group_fields.test.ts
new file mode 100644
index 000000000000..e83287a139dd
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/group_fields.test.ts
@@ -0,0 +1,114 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { groupFields } from './group_fields';
+import { getDefaultFieldFilter } from './field_filter';
+
+describe('group_fields', function() {
+ it('should group fields in selected, popular, unpopular group', function() {
+ const fields = [
+ {
+ name: 'category',
+ type: 'string',
+ esTypes: ['text'],
+ count: 1,
+ scripted: false,
+ searchable: true,
+ aggregatable: true,
+ readFromDocValues: true,
+ },
+ {
+ name: 'currency',
+ type: 'string',
+ esTypes: ['keyword'],
+ count: 0,
+ scripted: false,
+ searchable: true,
+ aggregatable: true,
+ readFromDocValues: true,
+ },
+ {
+ name: 'customer_birth_date',
+ type: 'date',
+ esTypes: ['date'],
+ count: 0,
+ scripted: false,
+ searchable: true,
+ aggregatable: true,
+ readFromDocValues: true,
+ },
+ ];
+
+ const fieldCounts = {
+ category: 1,
+ currency: 1,
+ customer_birth_date: 1,
+ };
+
+ const fieldFilterState = getDefaultFieldFilter();
+
+ const actual = groupFields(fields as any, ['currency'], 5, fieldCounts, fieldFilterState);
+ expect(actual).toMatchInlineSnapshot(`
+ Object {
+ "popular": Array [
+ Object {
+ "aggregatable": true,
+ "count": 1,
+ "esTypes": Array [
+ "text",
+ ],
+ "name": "category",
+ "readFromDocValues": true,
+ "scripted": false,
+ "searchable": true,
+ "type": "string",
+ },
+ ],
+ "selected": Array [
+ Object {
+ "aggregatable": true,
+ "count": 0,
+ "esTypes": Array [
+ "keyword",
+ ],
+ "name": "currency",
+ "readFromDocValues": true,
+ "scripted": false,
+ "searchable": true,
+ "type": "string",
+ },
+ ],
+ "unpopular": Array [
+ Object {
+ "aggregatable": true,
+ "count": 0,
+ "esTypes": Array [
+ "date",
+ ],
+ "name": "customer_birth_date",
+ "readFromDocValues": true,
+ "scripted": false,
+ "searchable": true,
+ "type": "date",
+ },
+ ],
+ }
+ `);
+ });
+});
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/group_fields.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/group_fields.tsx
new file mode 100644
index 000000000000..85ca8d6a4e15
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/group_fields.tsx
@@ -0,0 +1,78 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {
+ IndexPatternFieldList,
+ IndexPatternField,
+} from '../../../../../../../../../plugins/data/public';
+import { FieldFilterState, isFieldFiltered } from './field_filter';
+
+interface GroupedFields {
+ selected: IndexPatternField[];
+ popular: IndexPatternField[];
+ unpopular: IndexPatternField[];
+}
+
+/**
+ * group the fields into selected, popular and unpopular, filter by fieldFilterState
+ */
+export function groupFields(
+ fields: IndexPatternFieldList | null,
+ columns: string[],
+ popularLimit: number,
+ fieldCounts: Record,
+ fieldFilterState: FieldFilterState
+): GroupedFields {
+ const result: GroupedFields = {
+ selected: [],
+ popular: [],
+ unpopular: [],
+ };
+ if (!Array.isArray(fields) || !Array.isArray(columns) || typeof fieldCounts !== 'object') {
+ return result;
+ }
+
+ const popular = fields
+ .filter(field => !columns.includes(field.name) && field.count)
+ .sort((a: IndexPatternField, b: IndexPatternField) => (b.count || 0) - (a.count || 0))
+ .map(field => field.name)
+ .slice(0, popularLimit);
+
+ const compareFn = (a: IndexPatternField, b: IndexPatternField) => {
+ if (!a.displayName) {
+ return 0;
+ }
+ return a.displayName.localeCompare(b.displayName || '');
+ };
+ const fieldsSorted = fields.sort(compareFn);
+
+ for (const field of fieldsSorted) {
+ if (!isFieldFiltered(field, fieldFilterState, fieldCounts)) {
+ continue;
+ }
+ if (columns.includes(field.name)) {
+ result.selected.push(field);
+ } else if (popular.includes(field.name) && field.type !== '_source') {
+ result.popular.push(field);
+ } else if (field.type !== '_source') {
+ result.unpopular.push(field);
+ }
+ }
+
+ return result;
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/visualize_url_utils.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/visualize_url_utils.ts
new file mode 100644
index 000000000000..d146d212055b
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/lib/visualize_url_utils.ts
@@ -0,0 +1,188 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import uuid from 'uuid/v4';
+import rison from 'rison-node';
+import { parse, stringify } from 'query-string';
+import {
+ IFieldType,
+ IIndexPattern,
+ IndexPatternField,
+ KBN_FIELD_TYPES,
+} from '../../../../../../../../../plugins/data/public';
+import { AppState } from '../../../angular/discover_state';
+import { DiscoverServices } from '../../../../build_services';
+import {
+ VisualizationsStart,
+ VisTypeAlias,
+} from '../../../../../../../../../plugins/visualizations/public';
+
+function getMapsAppBaseUrl(visualizations: VisualizationsStart) {
+ const mapsAppVisAlias = visualizations.getAliases().find(({ name }) => {
+ return name === 'maps';
+ });
+ return mapsAppVisAlias ? mapsAppVisAlias.aliasUrl : null;
+}
+
+export function isMapsAppRegistered(visualizations: VisualizationsStart) {
+ return visualizations.getAliases().some(({ name }: VisTypeAlias) => {
+ return name === 'maps';
+ });
+}
+
+export function isFieldVisualizable(field: IFieldType, visualizations: VisualizationsStart) {
+ if (field.name === '_id') {
+ // Else you'd get a 'Fielddata access on the _id field is disallowed' error on ES side.
+ return false;
+ }
+ if (
+ (field.type === KBN_FIELD_TYPES.GEO_POINT || field.type === KBN_FIELD_TYPES.GEO_SHAPE) &&
+ isMapsAppRegistered(visualizations)
+ ) {
+ return true;
+ }
+ return field.visualizable;
+}
+
+export function getMapsAppUrl(
+ field: IFieldType,
+ indexPattern: IIndexPattern,
+ appState: AppState,
+ columns: string[],
+ services: DiscoverServices
+) {
+ const mapAppParams = new URLSearchParams();
+
+ // Copy global state
+ const locationSplit = window.location.href.split('discover?');
+ if (locationSplit.length > 1) {
+ const discoverParams = new URLSearchParams(locationSplit[1]);
+ const globalStateUrlValue = discoverParams.get('_g');
+ if (globalStateUrlValue) {
+ mapAppParams.set('_g', globalStateUrlValue);
+ }
+ }
+
+ // Copy filters and query in app state
+ const mapsAppState: any = {
+ filters: appState.filters || [],
+ };
+ if (appState.query) {
+ mapsAppState.query = appState.query;
+ }
+ // @ts-ignore
+ mapAppParams.set('_a', rison.encode(mapsAppState));
+
+ // create initial layer descriptor
+ const hasColumns = columns && columns.length && columns[0] !== '_source';
+ const supportsClustering = field.aggregatable;
+ mapAppParams.set(
+ 'initialLayers',
+ // @ts-ignore
+ rison.encode_array([
+ {
+ id: uuid(),
+ label: indexPattern.title,
+ sourceDescriptor: {
+ id: uuid(),
+ type: 'ES_SEARCH',
+ geoField: field.name,
+ tooltipProperties: hasColumns ? columns : [],
+ indexPatternId: indexPattern.id,
+ scalingType: supportsClustering ? 'CLUSTERS' : 'LIMIT',
+ },
+ visible: true,
+ type: supportsClustering ? 'BLENDED_VECTOR' : 'VECTOR',
+ },
+ ])
+ );
+
+ return services.addBasePath(
+ `${getMapsAppBaseUrl(services.visualizations)}?${mapAppParams.toString()}`
+ );
+}
+
+export function getVisualizeUrl(
+ field: IndexPatternField,
+ indexPattern: IIndexPattern,
+ state: AppState,
+ columns: string[],
+ services: DiscoverServices
+) {
+ const aggsTermSize = services.uiSettings.get('discover:aggs:terms:size');
+ const urlParams = parse(services.history.location.search) as Record;
+
+ if (
+ (field.type === KBN_FIELD_TYPES.GEO_POINT || field.type === KBN_FIELD_TYPES.GEO_SHAPE) &&
+ isMapsAppRegistered(services.visualizations)
+ ) {
+ return getMapsAppUrl(field, indexPattern, state, columns, services);
+ }
+
+ let agg;
+ const isGeoPoint = field.type === KBN_FIELD_TYPES.GEO_POINT;
+ const type = isGeoPoint ? 'tile_map' : 'histogram';
+ // If we're visualizing a date field, and our index is time based (and thus has a time filter),
+ // then run a date histogram
+ if (field.type === 'date' && indexPattern.timeFieldName === field.name) {
+ agg = {
+ type: 'date_histogram',
+ schema: 'segment',
+ params: {
+ field: field.name,
+ interval: 'auto',
+ },
+ };
+ } else if (isGeoPoint) {
+ agg = {
+ type: 'geohash_grid',
+ schema: 'segment',
+ params: {
+ field: field.name,
+ precision: 3,
+ },
+ };
+ } else {
+ agg = {
+ type: 'terms',
+ schema: 'segment',
+ params: {
+ field: field.name,
+ size: parseInt(aggsTermSize, 10),
+ orderBy: '2',
+ },
+ };
+ }
+ const linkUrlParams = {
+ ...urlParams,
+ ...{
+ indexPattern: state.index!,
+ type,
+ _a: rison.encode({
+ filters: state.filters || [],
+ query: state.query,
+ vis: {
+ type,
+ aggs: [{ schema: 'metric', type: 'count', id: '2' }, agg],
+ },
+ } as any),
+ },
+ };
+
+ return `#/visualize/create?${stringify(linkUrlParams)}`;
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/string_progress_bar.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/string_progress_bar.tsx
similarity index 80%
rename from src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/string_progress_bar.tsx
rename to src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/string_progress_bar.tsx
index 0c5e7fa69357..7ea41aa4bf27 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/string_progress_bar.tsx
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/string_progress_bar.tsx
@@ -18,14 +18,13 @@
*/
import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiProgress, EuiText, EuiToolTip } from '@elastic/eui';
-import { wrapInI18nContext } from '../../../kibana_services';
interface Props {
percent: number;
count: number;
}
-function StringFieldProgressBar(props: Props) {
+export function StringFieldProgressBar(props: Props) {
return (
-
+
@@ -50,7 +49,3 @@ function StringFieldProgressBar(props: Props) {
);
}
-
-export function createStringFieldProgressBarDirective(reactDirective: any) {
- return reactDirective(wrapInI18nContext(StringFieldProgressBar));
-}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/types.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/types.ts
similarity index 78%
rename from src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/types.ts
rename to src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/types.ts
index 302bf5165777..a1d71b4d3447 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/types.ts
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/types.ts
@@ -21,3 +21,18 @@ export interface IndexPatternRef {
id: string;
title: string;
}
+
+export interface FieldDetails {
+ error: string;
+ exists: number;
+ total: boolean;
+ buckets: Bucket[];
+ visualizeUrl: string;
+}
+
+export interface Bucket {
+ display: string;
+ value: string;
+ percent: number;
+ count: number;
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/embeddable/search_embeddable.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/embeddable/search_embeddable.ts
index d09b7612af49..f8e769d83744 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/embeddable/search_embeddable.ts
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/embeddable/search_embeddable.ts
@@ -16,6 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
+import angular from 'angular';
import _ from 'lodash';
import * as Rx from 'rxjs';
import { Subscription } from 'rxjs';
@@ -23,7 +24,7 @@ import { i18n } from '@kbn/i18n';
import {
UiActionsStart,
APPLY_FILTER_TRIGGER,
-} from '../../../../../../..//plugins/ui_actions/public';
+} from '../../../../../../../plugins/ui_actions/public';
import { RequestAdapter, Adapters } from '../../../../../../../plugins/inspector/public';
import {
esFilters,
@@ -34,14 +35,13 @@ import {
Query,
IFieldType,
} from '../../../../../../../plugins/data/public';
-import { Container, Embeddable } from '../../../../../embeddable_api/public/np_ready/public';
+import { Container, Embeddable } from '../../../../../../../plugins/embeddable/public';
import * as columnActions from '../angular/doc_table/actions/columns';
import searchTemplate from './search_template.html';
import { ISearchEmbeddable, SearchInput, SearchOutput } from './types';
import { SortOrder } from '../angular/doc_table/components/table_header/helpers';
import { getSortForSearchSource } from '../angular/doc_table/lib/get_sort_for_search_source';
import {
- angular,
getRequestInspectorStats,
getResponseInspectorStats,
getServices,
diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg.tsx
index 2a4527320762..83fbf70c9099 100644
--- a/src/legacy/core_plugins/vis_default_editor/public/components/agg.tsx
+++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg.tsx
@@ -35,6 +35,8 @@ import { AGGS_ACTION_KEYS, AggsAction } from './agg_group_state';
import { RowsOrColumnsControl } from './controls/rows_or_columns';
import { RadiusRatioOptionControl } from './controls/radius_ratio_option';
import { getSchemaByName } from '../schemas';
+import { TimeRange } from '../../../../../plugins/data/public';
+import { buildAggDescription } from './agg_params_helper';
export interface DefaultEditorAggProps extends DefaultEditorAggCommonProps {
agg: IAggConfig;
@@ -46,6 +48,7 @@ export interface DefaultEditorAggProps extends DefaultEditorAggCommonProps {
isLastBucket: boolean;
isRemovable: boolean;
setAggsState: React.Dispatch;
+ timeRange?: TimeRange;
}
function DefaultEditorAgg({
@@ -69,6 +72,7 @@ function DefaultEditorAgg({
removeAgg,
setAggsState,
schemas,
+ timeRange,
}: DefaultEditorAggProps) {
const [isEditorOpen, setIsEditorOpen] = useState((agg as any).brandNew);
const [validState, setValidState] = useState(true);
@@ -103,18 +107,15 @@ function DefaultEditorAgg({
}
}
- // A description of the aggregation, for displaying in the collapsed agg header
- let aggDescription = '';
+ const [aggDescription, setAggDescription] = useState(buildAggDescription(agg));
- if (agg.type && agg.type.makeLabel) {
- try {
- aggDescription = agg.type.makeLabel(agg);
- } catch (e) {
- // Date Histogram's `makeLabel` implementation invokes 'write' method for each param, including interval's 'write',
- // which throws an error when interval is undefined.
- aggDescription = '';
+ // This useEffect is required to update the timeRange value and initiate rerender to keep labels up to date (Issue #57822).
+ useEffect(() => {
+ if (timeRange && aggName === 'date_histogram') {
+ agg.aggConfigs.setTimeRange(timeRange);
}
- }
+ setAggDescription(buildAggDescription(agg));
+ }, [agg, aggName, timeRange]);
useEffect(() => {
if (isLastBucketAgg && ['date_histogram', 'histogram'].includes(aggName)) {
diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx
index 08b69ef37f52..f50abc3ebb59 100644
--- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx
+++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx
@@ -42,6 +42,7 @@ import {
} from './agg_group_helper';
import { aggGroupReducer, initAggsState, AGGS_ACTION_KEYS } from './agg_group_state';
import { Schema, getSchemasByGroup } from '../schemas';
+import { TimeRange } from '../../../../../plugins/data/public';
export interface DefaultEditorAggGroupProps extends DefaultEditorAggCommonProps {
schemas: Schema[];
@@ -49,6 +50,7 @@ export interface DefaultEditorAggGroupProps extends DefaultEditorAggCommonProps
reorderAggs: ReorderAggs;
setValidity(modelName: string, value: boolean): void;
setTouched(isTouched: boolean): void;
+ timeRange?: TimeRange;
}
function DefaultEditorAggGroup({
@@ -67,6 +69,7 @@ function DefaultEditorAggGroup({
reorderAggs,
setTouched,
setValidity,
+ timeRange,
}: DefaultEditorAggGroupProps) {
const groupNameLabel = (search.aggs.aggGroupNamesMap() as any)[groupName];
// e.g. buckets can have no aggs
@@ -185,6 +188,7 @@ function DefaultEditorAggGroup({
removeAgg={removeAgg}
setAggsState={setAggsState}
schemas={schemas}
+ timeRange={timeRange}
/>
)}
diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts
index 10590e1a59f4..073cb7d5ac66 100644
--- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts
+++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts
@@ -174,4 +174,17 @@ function isInvalidParamsTouched(
return invalidParams.every(param => param.touched);
}
-export { getAggParamsToRender, getAggTypeOptions, isInvalidParamsTouched };
+function buildAggDescription(agg: IAggConfig) {
+ let description = '';
+ if (agg.type && agg.type.makeLabel) {
+ try {
+ description = agg.type.makeLabel(agg);
+ } catch (e) {
+ // Date Histogram's `makeLabel` implementation invokes 'write' method for each param, including interval's 'write',
+ // which throws an error when interval is undefined.
+ }
+ }
+ return description;
+}
+
+export { getAggParamsToRender, getAggTypeOptions, isInvalidParamsTouched, buildAggDescription };
diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/time_interval.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/time_interval.tsx
index 9aacd6a10262..971a62faf7d7 100644
--- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/time_interval.tsx
+++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/time_interval.tsx
@@ -61,7 +61,7 @@ function validateInterval(
timeBase?: string
) {
if (definedOption) {
- return { isValid: true };
+ return { isValid: true, interval: agg.buckets?.getInterval() };
}
if (!value) {
@@ -131,7 +131,7 @@ function TimeIntervalParamEditor({
const scaledHelpText =
interval && interval.scaled ? (
-
+
@@ -128,6 +131,7 @@ function DefaultEditorDataTab({
>
diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx
index 29039715066b..071e10682e22 100644
--- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx
+++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx
@@ -33,6 +33,7 @@ import { PersistedState } from '../../../../../../plugins/visualizations/public'
import { SavedSearch } from '../../../../../../plugins/discover/public';
import { AggGroupNames } from '../../../../../../plugins/data/public';
import { getSchemasByGroup } from '../../schemas';
+import { TimeRange } from '../../../../../../plugins/data/public';
interface DefaultEditorSideBarProps {
isCollapsed: boolean;
@@ -43,6 +44,7 @@ interface DefaultEditorSideBarProps {
isLinkedSearch: boolean;
eventEmitter: EventEmitter;
savedSearch?: SavedSearch;
+ timeRange: TimeRange;
}
function DefaultEditorSideBar({
@@ -54,6 +56,7 @@ function DefaultEditorSideBar({
isLinkedSearch,
eventEmitter,
savedSearch,
+ timeRange,
}: DefaultEditorSideBarProps) {
const [selectedTab, setSelectedTab] = useState(optionTabs[0].name);
const [isDirty, setDirty] = useState(false);
@@ -214,6 +217,7 @@ function DefaultEditorSideBar({
);
diff --git a/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx b/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx
index b504dfd6a55e..899b9c1b5fd6 100644
--- a/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx
+++ b/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx
@@ -92,6 +92,7 @@ function DefaultEditor({
uiState={uiState}
isLinkedSearch={linked}
savedSearch={savedSearch}
+ timeRange={timeRange}
eventEmitter={eventEmitter}
/>
diff --git a/src/legacy/ui/public/chrome/api/sub_url_hooks.js b/src/legacy/ui/public/chrome/api/sub_url_hooks.js
index 27d147b1ffc7..f147aef7b4b7 100644
--- a/src/legacy/ui/public/chrome/api/sub_url_hooks.js
+++ b/src/legacy/ui/public/chrome/api/sub_url_hooks.js
@@ -17,11 +17,10 @@
* under the License.
*/
-import url from 'url';
-
import { unhashUrl } from '../../../../../plugins/kibana_utils/public';
import { toastNotifications } from '../../notify/toasts';
import { npSetup } from '../../new_platform';
+import { areHashesDifferentButDecodedHashesEquals } from './sub_url_hooks_utils';
export function registerSubUrlHooks(angularModule, internals) {
angularModule.run(($rootScope, Private, $location) => {
@@ -49,17 +48,10 @@ export function registerSubUrlHooks(angularModule, internals) {
$rootScope.$on('$locationChangeStart', (e, newUrl) => {
// This handler fixes issue #31238 where browser back navigation
// fails due to angular 1.6 parsing url encoded params wrong.
- const parsedAbsUrl = url.parse($location.absUrl());
- const absUrlHash = parsedAbsUrl.hash ? parsedAbsUrl.hash.slice(1) : '';
- const decodedAbsUrlHash = decodeURIComponent(absUrlHash);
-
- const parsedNewUrl = url.parse(newUrl);
- const newHash = parsedNewUrl.hash ? parsedNewUrl.hash.slice(1) : '';
- const decodedHash = decodeURIComponent(newHash);
-
- if (absUrlHash !== newHash && decodedHash === decodedAbsUrlHash) {
+ if (areHashesDifferentButDecodedHashesEquals($location.absUrl(), newUrl)) {
// replace the urlencoded hash with the version that angular sees.
- $location.url(absUrlHash).replace();
+ const newHash = newUrl.split('#')[1] || '';
+ $location.url(newHash).replace();
}
});
diff --git a/src/legacy/ui/public/chrome/api/sub_url_hooks_utils.test.ts b/src/legacy/ui/public/chrome/api/sub_url_hooks_utils.test.ts
new file mode 100644
index 000000000000..4dec52630234
--- /dev/null
+++ b/src/legacy/ui/public/chrome/api/sub_url_hooks_utils.test.ts
@@ -0,0 +1,58 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { areHashesDifferentButDecodedHashesEquals } from './sub_url_hooks_utils';
+
+test('false for different hashes', () => {
+ const url1 = `https://localhost/kibana/#/dashboard/id`;
+ const url2 = `https://localhost/kibana/#/dashboard/DIFFERENT`;
+ expect(areHashesDifferentButDecodedHashesEquals(url1, url2)).toBeFalsy();
+});
+
+test('false for same hashes', () => {
+ const hash = `/dashboard/id?_a=(filters:!(),query:(language:kuery,query:''))&_g=(filters:!(),time:(from:now-120m,to:now))`;
+ const url1 = `https://localhost/kibana/#/${hash}`;
+ expect(areHashesDifferentButDecodedHashesEquals(url1, url1)).toBeFalsy();
+});
+
+test('true for same hashes, but one is encoded', () => {
+ const hash = `/dashboard/id?_a=(filters:!(),query:(language:kuery,query:''))&_g=(filters:!(),time:(from:now-120m,to:now))`;
+ const url1 = `https://localhost/kibana/#/${hash}`;
+ const url2 = `https://localhost/kibana/#/${encodeURIComponent(hash)}`;
+ expect(areHashesDifferentButDecodedHashesEquals(url1, url2)).toBeTruthy();
+});
+
+/**
+ * This edge case occurs when trying to navigate within kibana app using core's `navigateToApp` api
+ * and there is reserved characters in hash (see: query:'' part)
+ * For example:
+ * ```ts
+ * navigateToApp('kibana', {
+ * path: '#/dashboard/f8bc19f0-6918-11ea-9258-a74c2ded064d?_a=(filters:!(),query:(language:kuery,query:''))&_g=(filters:!(),time:(from:now-120m,to:now))'
+ * })
+ * ```
+ * Core internally is using url.parse which parses ' -> %27 and performs the navigation
+ * Then angular decodes it back and causes redundant history record if not the fix which is covered by the test below
+ */
+test("true for same hashes, but one has reserved character (') encoded", () => {
+ const hash = `/dashboard/id?_a=(filters:!(),query:(language:kuery,query:''))&_g=(filters:!(),time:(from:now-120m,to:now))`;
+ const url1 = `https://localhost/kibana/#/${hash}`;
+ const url2 = `https://localhost/kibana/#/${hash.replace(/\'/g, '%27')}`;
+ expect(areHashesDifferentButDecodedHashesEquals(url1, url2)).toBeTruthy();
+});
diff --git a/src/legacy/core_plugins/embeddable_api/index.ts b/src/legacy/ui/public/chrome/api/sub_url_hooks_utils.ts
similarity index 67%
rename from src/legacy/core_plugins/embeddable_api/index.ts
rename to src/legacy/ui/public/chrome/api/sub_url_hooks_utils.ts
index 52206e3d0f10..8517877acd38 100644
--- a/src/legacy/core_plugins/embeddable_api/index.ts
+++ b/src/legacy/ui/public/chrome/api/sub_url_hooks_utils.ts
@@ -17,9 +17,13 @@
* under the License.
*/
-import { LegacyPluginApi, LegacyPluginSpec, ArrayOrItem } from 'src/legacy/plugin_discovery/types';
+export function areHashesDifferentButDecodedHashesEquals(urlA: string, urlB: string): boolean {
+ const getHash = (url: string) => url.split('#')[1] ?? '';
+ const hashA = getHash(urlA);
+ const decodedHashA = decodeURIComponent(hashA);
-// eslint-disable-next-line import/no-default-export
-export default function(kibana: LegacyPluginApi): ArrayOrItem {
- return new kibana.Plugin({});
+ const hashB = getHash(urlB);
+ const decodedHashB = decodeURIComponent(hashB);
+
+ return hashA !== hashB && decodedHashA === decodedHashB;
}
diff --git a/src/legacy/ui/public/styles/_legacy/components/_index.scss b/src/legacy/ui/public/styles/_legacy/components/_index.scss
index 4a50a0430d55..cfae0700bb71 100644
--- a/src/legacy/ui/public/styles/_legacy/components/_index.scss
+++ b/src/legacy/ui/public/styles/_legacy/components/_index.scss
@@ -7,7 +7,6 @@
@import './navbar';
@import './config';
@import './pagination';
-@import './sidebar';
@import './spinner';
@import './table';
@import './truncate';
diff --git a/src/legacy/ui/public/styles/_legacy/components/_sidebar.scss b/src/legacy/ui/public/styles/_legacy/components/_sidebar.scss
deleted file mode 100644
index d44129b6ec84..000000000000
--- a/src/legacy/ui/public/styles/_legacy/components/_sidebar.scss
+++ /dev/null
@@ -1,127 +0,0 @@
-// ONLY USED IN DISCOVER
-
-.sidebar-container {
- padding-left: 0 !important;
- padding-right: 0 !important;
- background-color: $euiColorLightestShade;
- border-right-color: transparent;
- border-bottom-color: transparent;
-
- .sidebar-well {
- background-color: lightOrDarkTheme(tint($euiColorPrimary, 90%), $euiColorLightShade);
- }
-
- .sidebar-list {
- .sidebar-controls {
- border-radius: $euiBorderRadius;
- margin-right: -13px;
- margin-top: $euiSizeXS / 2;
-
- .navbar-btn-link {
- padding-left: $euiSizeS;
- padding-right: $euiSizeS;
- }
-
- .sidebar-controls-error {
- cursor: default;
- }
- }
-
- ul {
- list-style: none;
- margin-bottom: 0;
- }
-
- .sidebar-item {
- border-top-color: transparent;
- font-size: $euiFontSizeXS;
- border-top: solid 1px transparent;
- border-bottom: solid 1px transparent;
- line-height: normal;
-
- label {
- @include __legacyLabelStyles__bad;
- margin-bottom: $euiSizeXS;
- display: block;
- }
-
- &.active {
- background-color: shade($euiColorLightestShade, 10%);
- color: $euiColorDarkestShade;
- border-color: $euiColorLightShade;
- }
- }
-
- .sidebar-item-title,
- .sidebar-item-text {
- margin: 0;
- padding: $euiSizeXS 0;
- text-align: center;
- width: 100%;
- border: none;
- border-radius: 0;
- }
-
- .sidebar-item-title {
- @include euiTextTruncate;
- text-align: left;
-
- &.full-title {
- white-space: normal;
- }
- }
-
- .sidebar-item-text {
- background: $euiColorEmptyShade;
- }
- }
-
- .sidebar-list-header {
- .sidebar-list-header-heading {
- color: $euiColorDarkestShade;
- border: 1px solid transparent;
- }
-
- .sidebar-list-header-label {
- padding-left: $euiSizeS;
- font-size: $euiFontSizeXS;
- line-height: $euiLineHeight;
- font-weight: $euiFontWeightBold;
- color: $euiColorDarkShade;
- border-bottom: 1px solid $euiColorLightShade;
- }
- }
-
- .index-pattern {
- font-weight: $euiFontWeightBold;
- padding: $euiSizeXS $euiSizeS;
- display: flex;
- justify-content: space-between;
- background-color: shadeOrTint($euiColorPrimary, 60%, 60%);
- color: $euiColorEmptyShade;
- line-height: $euiSizeL;
-
- .index-pattern-label {
- font-size: $euiFontSizeS;
- font-weight: $euiFontWeightBold;
- margin: 0;
- }
-
- > * {
- flex: 0 1 auto;
- align-self: center;
- }
- }
-}
-
-.indexPattern__container {
- display: flex;
- align-items: center;
- height: $euiSize * 3;
- margin-top: -$euiSizeS;
-}
-
-.indexPattern__triggerButton {
- @include euiTitle('xs');
- line-height: $euiSizeXXL;
-}
diff --git a/src/legacy/ui/public/vis/map/service_settings.js b/src/legacy/ui/public/vis/map/service_settings.js
index 9f3d21831e3d..a014aeb182c6 100644
--- a/src/legacy/ui/public/vis/map/service_settings.js
+++ b/src/legacy/ui/public/vis/map/service_settings.js
@@ -53,6 +53,10 @@ uiModules
tileApiUrl: mapConfig.emsTileApiUrl,
htmlSanitizer: $sanitize,
landingPageUrl: mapConfig.emsLandingPageUrl,
+ // Wrap to avoid errors passing window fetch
+ fetchFunction: function(...args) {
+ return fetch(...args);
+ },
});
}
diff --git a/src/plugins/dashboard/public/url_generator.test.ts b/src/plugins/dashboard/public/url_generator.test.ts
index 5dfc47b694f6..d48aacc1d8c1 100644
--- a/src/plugins/dashboard/public/url_generator.test.ts
+++ b/src/plugins/dashboard/public/url_generator.test.ts
@@ -21,6 +21,7 @@ import { createDirectAccessDashboardLinkGenerator } from './url_generator';
import { hashedItemStore } from '../../kibana_utils/public';
// eslint-disable-next-line
import { mockStorage } from '../../kibana_utils/public/storage/hashed_item_store/mock';
+import { esFilters } from '../../data/public';
const APP_BASE_PATH: string = 'xyz/app/kibana';
@@ -50,12 +51,13 @@ describe('dashboard url generator', () => {
);
});
- test('creates a link with filters, time range and query to a saved object', async () => {
+ test('creates a link with filters, time range, refresh interval and query to a saved object', async () => {
const generator = createDirectAccessDashboardLinkGenerator(() =>
Promise.resolve({ appBasePath: APP_BASE_PATH, useHashedUrl: false })
);
const url = await generator.createUrl!({
timeRange: { to: 'now', from: 'now-15m', mode: 'relative' },
+ refreshInterval: { pause: false, value: 300 },
dashboardId: '123',
filters: [
{
@@ -66,11 +68,22 @@ describe('dashboard url generator', () => {
},
query: { query: 'hi' },
},
+ {
+ meta: {
+ alias: null,
+ disabled: false,
+ negate: false,
+ },
+ query: { query: 'hi' },
+ $state: {
+ store: esFilters.FilterStateStore.GLOBAL_STATE,
+ },
+ },
],
query: { query: 'bye', language: 'kuery' },
});
expect(url).toMatchInlineSnapshot(
- `"xyz/app/kibana#/dashboard/123?_a=(filters:!((meta:(alias:!n,disabled:!f,negate:!f),query:(query:hi))),query:(language:kuery,query:bye))&_g=(time:(from:now-15m,mode:relative,to:now))"`
+ `"xyz/app/kibana#/dashboard/123?_a=(filters:!((meta:(alias:!n,disabled:!f,negate:!f),query:(query:hi))),query:(language:kuery,query:bye))&_g=(filters:!(('$state':(store:globalState),meta:(alias:!n,disabled:!f,negate:!f),query:(query:hi))),refreshInterval:(pause:!f,value:300),time:(from:now-15m,mode:relative,to:now))"`
);
});
diff --git a/src/plugins/dashboard/public/url_generator.ts b/src/plugins/dashboard/public/url_generator.ts
index 5f1255bc9d45..0fdf395e75bc 100644
--- a/src/plugins/dashboard/public/url_generator.ts
+++ b/src/plugins/dashboard/public/url_generator.ts
@@ -17,7 +17,14 @@
* under the License.
*/
-import { TimeRange, Filter, Query } from '../../data/public';
+import {
+ TimeRange,
+ Filter,
+ Query,
+ esFilters,
+ QueryState,
+ RefreshInterval,
+} from '../../data/public';
import { setStateToKbnUrl } from '../../kibana_utils/public';
import { UrlGeneratorsDefinition, UrlGeneratorState } from '../../share/public';
@@ -36,10 +43,15 @@ export type DashboardAppLinkGeneratorState = UrlGeneratorState<{
* Optionally set the time range in the time picker.
*/
timeRange?: TimeRange;
+
+ /**
+ * Optionally set the refresh interval.
+ */
+ refreshInterval?: RefreshInterval;
+
/**
* Optionally apply filers. NOTE: if given and used in conjunction with `dashboardId`, and the
- * saved dashboard has filters saved with it, this will _replace_ those filters. This will set
- * app filters, not global filters.
+ * saved dashboard has filters saved with it, this will _replace_ those filters.
*/
filters?: Filter[];
/**
@@ -64,21 +76,32 @@ export const createDirectAccessDashboardLinkGenerator = (
const appBasePath = startServices.appBasePath;
const hash = state.dashboardId ? `dashboard/${state.dashboardId}` : `dashboard`;
+ const cleanEmptyKeys = (stateObj: Record) => {
+ Object.keys(stateObj).forEach(key => {
+ if (stateObj[key] === undefined) {
+ delete stateObj[key];
+ }
+ });
+ return stateObj;
+ };
+
const appStateUrl = setStateToKbnUrl(
STATE_STORAGE_KEY,
- {
+ cleanEmptyKeys({
query: state.query,
- filters: state.filters,
- },
+ filters: state.filters?.filter(f => !esFilters.isFilterPinned(f)),
+ }),
{ useHash },
`${appBasePath}#/${hash}`
);
- return setStateToKbnUrl(
+ return setStateToKbnUrl(
GLOBAL_STATE_STORAGE_KEY,
- {
+ cleanEmptyKeys({
time: state.timeRange,
- },
+ filters: state.filters?.filter(f => esFilters.isFilterPinned(f)),
+ refreshInterval: state.refreshInterval,
+ }),
{ useHash },
appStateUrl
);
diff --git a/src/plugins/data/public/query/state_sync/connect_to_query_state.test.ts b/src/plugins/data/public/query/state_sync/connect_to_query_state.test.ts
index 5da929c441cd..06e4c1c8be6d 100644
--- a/src/plugins/data/public/query/state_sync/connect_to_query_state.test.ts
+++ b/src/plugins/data/public/query/state_sync/connect_to_query_state.test.ts
@@ -463,3 +463,97 @@ describe('connect_to_app_state', () => {
});
});
});
+
+describe('filters with different state', () => {
+ let queryServiceStart: QueryStart;
+ let filterManager: FilterManager;
+ let state: BaseStateContainer;
+ let stateSub: Subscription;
+ let stateChangeTriggered = jest.fn();
+ let filterManagerChangeSub: Subscription;
+ let filterManagerChangeTriggered = jest.fn();
+
+ let filter: Filter;
+
+ beforeEach(() => {
+ const queryService = new QueryService();
+ queryService.setup({
+ uiSettings: setupMock.uiSettings,
+ storage: new Storage(new StubBrowserStorage()),
+ });
+ queryServiceStart = queryService.start(startMock.savedObjects);
+ filterManager = queryServiceStart.filterManager;
+
+ state = createStateContainer({});
+ stateChangeTriggered = jest.fn();
+ stateSub = state.state$.subscribe(stateChangeTriggered);
+
+ filterManagerChangeTriggered = jest.fn();
+ filterManagerChangeSub = filterManager.getUpdates$().subscribe(filterManagerChangeTriggered);
+
+ filter = getFilter(FilterStateStore.GLOBAL_STATE, true, true, 'key1', 'value1');
+ });
+
+ // applies filter state changes, changes only internal $state.store value
+ function runChanges() {
+ filter = { ...filter, $state: { store: FilterStateStore.GLOBAL_STATE } };
+
+ state.set({
+ filters: [filter],
+ });
+
+ filter = { ...filter, $state: { store: FilterStateStore.APP_STATE } };
+
+ state.set({
+ filters: [filter],
+ });
+
+ filter = { ...filter };
+ delete filter.$state;
+
+ state.set({
+ filters: [filter],
+ });
+ }
+
+ test('when syncing all filters, changes to filter.state$ should be taken into account', () => {
+ const stop = connectToQueryState(queryServiceStart, state, {
+ filters: true,
+ });
+
+ runChanges();
+
+ expect(filterManagerChangeTriggered).toBeCalledTimes(3);
+
+ stop();
+ });
+
+ test('when syncing app state filters, changes to filter.state$ should be ignored', () => {
+ const stop = connectToQueryState(queryServiceStart, state, {
+ filters: FilterStateStore.APP_STATE,
+ });
+
+ runChanges();
+
+ expect(filterManagerChangeTriggered).toBeCalledTimes(1);
+
+ stop();
+ });
+
+ test('when syncing global state filters, changes to filter.state$ should be ignored', () => {
+ const stop = connectToQueryState(queryServiceStart, state, {
+ filters: FilterStateStore.GLOBAL_STATE,
+ });
+
+ runChanges();
+
+ expect(filterManagerChangeTriggered).toBeCalledTimes(1);
+
+ stop();
+ });
+
+ afterEach(() => {
+ stateSub.unsubscribe();
+ filterManagerChangeSub.unsubscribe();
+ });
+});
diff --git a/src/plugins/data/public/query/state_sync/connect_to_query_state.ts b/src/plugins/data/public/query/state_sync/connect_to_query_state.ts
index 331d8969f248..3256c1cbd65a 100644
--- a/src/plugins/data/public/query/state_sync/connect_to_query_state.ts
+++ b/src/plugins/data/public/query/state_sync/connect_to_query_state.ts
@@ -91,7 +91,10 @@ export const connectToQueryState = (
} else if (syncConfig.filters === FilterStateStore.GLOBAL_STATE) {
if (
!initialState.filters ||
- !compareFilters(initialState.filters, filterManager.getGlobalFilters(), COMPARE_ALL_OPTIONS)
+ !compareFilters(initialState.filters, filterManager.getGlobalFilters(), {
+ ...COMPARE_ALL_OPTIONS,
+ state: false,
+ })
) {
initialState.filters = filterManager.getGlobalFilters();
initialDirty = true;
@@ -99,7 +102,10 @@ export const connectToQueryState = (
} else if (syncConfig.filters === FilterStateStore.APP_STATE) {
if (
!initialState.filters ||
- !compareFilters(initialState.filters, filterManager.getAppFilters(), COMPARE_ALL_OPTIONS)
+ !compareFilters(initialState.filters, filterManager.getAppFilters(), {
+ ...COMPARE_ALL_OPTIONS,
+ state: false,
+ })
) {
initialState.filters = filterManager.getAppFilters();
initialDirty = true;
@@ -173,11 +179,21 @@ export const connectToQueryState = (
filterManager.setFilters(_.cloneDeep(filters));
}
} else if (syncConfig.filters === FilterStateStore.APP_STATE) {
- if (!compareFilters(filters, filterManager.getAppFilters(), COMPARE_ALL_OPTIONS)) {
+ if (
+ !compareFilters(filters, filterManager.getAppFilters(), {
+ ...COMPARE_ALL_OPTIONS,
+ state: false,
+ })
+ ) {
filterManager.setAppFilters(_.cloneDeep(filters));
}
} else if (syncConfig.filters === FilterStateStore.GLOBAL_STATE) {
- if (!compareFilters(filters, filterManager.getGlobalFilters(), COMPARE_ALL_OPTIONS)) {
+ if (
+ !compareFilters(filters, filterManager.getGlobalFilters(), {
+ ...COMPARE_ALL_OPTIONS,
+ state: false,
+ })
+ ) {
filterManager.setGlobalFilters(_.cloneDeep(filters));
}
}
diff --git a/src/plugins/discover/public/components/field_name/__snapshots__/field_name.test.tsx.snap b/src/plugins/discover/public/components/field_name/__snapshots__/field_name.test.tsx.snap
index 2424416f6f92..9f48e6e57e0f 100644
--- a/src/plugins/discover/public/components/field_name/__snapshots__/field_name.test.tsx.snap
+++ b/src/plugins/discover/public/components/field_name/__snapshots__/field_name.test.tsx.snap
@@ -2,7 +2,7 @@
exports[`FieldName renders a geo field, useShortDots is set to true 1`] = `
+
+
+
+ {fields.length > 0 && (
+ <>
+
+
+
+
+
+
+
+
+ -
+ {selectedFields.map((field: IndexPatternField, idx: number) => {
+ return (
+
-
+
+
+ );
+ })}
+
+
+
+
+
+
+ >
+ )}
+ {popularFields.length > 0 && (
+
+
+
+
+ setShowFields(!showFields)}
+ aria-label={
+ showFields
+ ? i18n.translate(
+ 'kbn.discover.fieldChooser.filter.indexAndFieldsSectionHideAriaLabel',
+ {
+ defaultMessage: 'Hide fields',
+ }
+ )
+ : i18n.translate(
+ 'kbn.discover.fieldChooser.filter.indexAndFieldsSectionShowAriaLabel',
+ {
+ defaultMessage: 'Show fields',
+ }
+ )
+ }
+ />
+
+
+
+
+
+
+
+ )}
+
+
+
+
+ -
+ {popularFields.map((field: IndexPatternField, idx: number) => {
+ return (
+
-
+
+
+ );
+ })}
+
-
+ {unpopularFields.map((field: IndexPatternField, idx: number) => {
+ return (
+
-
+
+
+ );
+ })}
+
{
- const field = {
- type: 'number',
- name: 'test.test.test',
- rowCount: 100,
- scripted: false,
- };
- const component = render( );
+ const component = render( );
expect(component).toMatchSnapshot();
});
test('FieldName renders a geo field, useShortDots is set to true', () => {
- const field = {
- type: 'geo_point',
- name: 'test.test.test',
- rowCount: 0,
- scripted: false,
- };
- const component = render( );
+ const component = render(
+
+ );
expect(component).toMatchSnapshot();
});
diff --git a/src/plugins/discover/public/components/field_name/field_name.tsx b/src/plugins/discover/public/components/field_name/field_name.tsx
index 63518aae28de..f7f1433328ad 100644
--- a/src/plugins/discover/public/components/field_name/field_name.tsx
+++ b/src/plugins/discover/public/components/field_name/field_name.tsx
@@ -17,51 +17,36 @@
* under the License.
*/
import React from 'react';
-import classNames from 'classnames';
import { EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui';
import { FieldIcon, FieldIconProps } from '../../../../kibana_react/public';
import { shortenDottedString } from '../../helpers';
import { getFieldTypeName } from './field_type_name';
-// property field is provided at discover's field chooser
// properties fieldType and fieldName are provided in kbn_doc_view
// this should be changed when both components are deangularized
interface Props {
- field?: {
- type: string;
- name: string;
- rowCount?: number;
- scripted?: boolean;
- };
- fieldName?: string;
- fieldType?: string;
+ fieldName: string;
+ fieldType: string;
useShortDots?: boolean;
fieldIconProps?: Omit;
+ scripted?: boolean;
}
-export function FieldName({ field, fieldName, fieldType, useShortDots, fieldIconProps }: Props) {
- const type = field ? String(field.type) : String(fieldType);
- const typeName = getFieldTypeName(type);
-
- const name = field ? String(field.name) : String(fieldName);
- const displayName = useShortDots ? shortenDottedString(name) : name;
-
- const noResults = field ? !field.rowCount && !field.scripted : false;
-
- const className = classNames('dscFieldName', {
- 'dscFieldName--noResults': noResults,
- });
+export function FieldName({
+ fieldName,
+ fieldType,
+ useShortDots,
+ fieldIconProps,
+ scripted = false,
+}: Props) {
+ const typeName = getFieldTypeName(fieldType);
+ const displayName = useShortDots ? shortenDottedString(fieldName) : fieldName;
return (
-
+
-
+
diff --git a/test/accessibility/apps/discover.ts b/test/accessibility/apps/discover.ts
index cf3d37d29b49..086b13ecee2b 100644
--- a/test/accessibility/apps/discover.ts
+++ b/test/accessibility/apps/discover.ts
@@ -63,7 +63,7 @@ export default function({ getService, getPageObjects }: FtrProviderContext) {
await a11y.testAppSnapshot();
});
- it.skip('Click on new to clear the search', async () => {
+ it('Click on new to clear the search', async () => {
await PageObjects.discover.clickNewSearchButton();
await a11y.testAppSnapshot();
});
@@ -121,7 +121,7 @@ export default function({ getService, getPageObjects }: FtrProviderContext) {
await a11y.testAppSnapshot();
});
- it.skip('Add more fields from sidebar', async () => {
+ it('Add more fields from sidebar', async () => {
for (const [columnName, value] of TEST_FILTER_COLUMN_NAMES) {
await PageObjects.discover.clickFieldListItem(columnName);
await PageObjects.discover.clickFieldListPlusFilter(columnName, value);
diff --git a/test/functional/apps/management/_scripted_fields.js b/test/functional/apps/management/_scripted_fields.js
index 65291c3c4772..d85d5a952d3e 100644
--- a/test/functional/apps/management/_scripted_fields.js
+++ b/test/functional/apps/management/_scripted_fields.js
@@ -388,7 +388,7 @@ export default function({ getService, getPageObjects }) {
await log.debug('filter by "Sep 17, 2015 @ 23:00" in the expanded scripted field list');
await PageObjects.discover.clickFieldListPlusFilter(
scriptedPainlessFieldName2,
- '2015-09-17 23:00'
+ '1442531297065'
);
await PageObjects.header.waitUntilLoadingHasFinished();
diff --git a/test/functional/apps/visualize/_area_chart.js b/test/functional/apps/visualize/_area_chart.js
index ebbeb01cbc91..8f2012d7f184 100644
--- a/test/functional/apps/visualize/_area_chart.js
+++ b/test/functional/apps/visualize/_area_chart.js
@@ -554,5 +554,76 @@ export default function({ getService, getPageObjects }) {
});
});
});
+
+ describe('date histogram interval', () => {
+ before(async () => {
+ await PageObjects.visualize.loadSavedVisualization('Visualization AreaChart');
+ await PageObjects.visChart.waitForVisualization();
+ });
+
+ beforeEach(async () => {
+ const fromTime = 'Sep 20, 2015 @ 00:00:00.000';
+ const toTime = 'Sep 20, 2015 @ 23:30:00.000';
+ await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime);
+ });
+
+ it('should update collapsed accordion label when time range is changed', async () => {
+ const accordionLabel = await find.byCssSelector(
+ '[data-test-subj="visEditorAggAccordion2"] .visEditorSidebar__aggGroupAccordionButtonContent'
+ );
+ let accordionLabelText = await accordionLabel.getVisibleText();
+ expect(accordionLabelText).to.include.string('per 30 minutes');
+ const fromTime = 'Sep 20, 2015 @ 08:30:00.000';
+ const toTime = 'Sep 20, 2015 @ 23:30:00.000';
+ await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime);
+ accordionLabelText = await accordionLabel.getVisibleText();
+ expect(accordionLabelText).to.include.string('per 10 minutes');
+ });
+
+ describe('expanded accordion', () => {
+ before(async () => await PageObjects.visEditor.toggleAccordion('visEditorAggAccordion2'));
+
+ it('should update label inside the opened accordion when scaled to milliseconds', async () => {
+ const isHelperScaledLabelExists = await find.existsByCssSelector(
+ '[data-test-subj="currentlyScaledText"]'
+ );
+ expect(isHelperScaledLabelExists).to.be(false);
+ await PageObjects.visEditor.setInterval('Millisecond');
+ const helperScaledLabelText = await testSubjects.getVisibleText('currentlyScaledText');
+ expect(helperScaledLabelText).to.include.string('to 10 minutes');
+ });
+
+ it('should display updated scaled label text after time range is changed', async () => {
+ await PageObjects.visEditor.setInterval('Millisecond');
+ const isHelperScaledLabelExists = await find.existsByCssSelector(
+ '[data-test-subj="currentlyScaledText"]'
+ );
+ expect(isHelperScaledLabelExists).to.be(true);
+ let helperScaledLabelText = await testSubjects.getVisibleText('currentlyScaledText');
+ expect(helperScaledLabelText).to.include.string('to 10 minutes');
+ const fromTime = 'Sep 20, 2015 @ 22:30:00.000';
+ const toTime = 'Sep 20, 2015 @ 23:30:00.000';
+ await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime);
+ helperScaledLabelText = await testSubjects.getVisibleText('currentlyScaledText');
+ expect(helperScaledLabelText).to.include.string('to 30 seconds');
+ });
+
+ it('should update scaled label text after custom interval is set and time range is changed', async () => {
+ await PageObjects.visEditor.setInterval('10s', { type: 'custom' });
+ await testSubjects.clickWhenNotDisabled('visualizeEditorRenderButton');
+ const isHelperScaledLabelExists = await find.existsByCssSelector(
+ '[data-test-subj="currentlyScaledText"]'
+ );
+ expect(isHelperScaledLabelExists).to.be(true);
+ let helperScaledLabelText = await testSubjects.getVisibleText('currentlyScaledText');
+ expect(helperScaledLabelText).to.include.string('to 10 minutes');
+ const fromTime = 'Sep 20, 2015 @ 21:30:00.000';
+ const toTime = 'Sep 20, 2015 @ 23:30:00.000';
+ await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime);
+ helperScaledLabelText = await testSubjects.getVisibleText('currentlyScaledText');
+ expect(helperScaledLabelText).to.include.string('to minute');
+ });
+ });
+ });
});
}
diff --git a/test/functional/fixtures/es_archiver/visualize/data.json b/test/functional/fixtures/es_archiver/visualize/data.json
index 845e9a5e0882..abca5a98bf7f 100644
--- a/test/functional/fixtures/es_archiver/visualize/data.json
+++ b/test/functional/fixtures/es_archiver/visualize/data.json
@@ -69,6 +69,27 @@
}
}
+{
+ "type": "doc",
+ "value": {
+ "id": "visualization:Visualization-AreaChart",
+ "index": ".kibana",
+ "source": {
+ "type": "visualization",
+ "visualization": {
+ "description": "AreaChart",
+ "kibanaSavedObjectMeta": {
+ "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}},\"filter\":[]}"
+ },
+ "title": "Visualization AreaChart",
+ "uiStateJSON": "{}",
+ "version": 1,
+ "visState": "{\"title\":\"Visualization AreaChart\",\"type\":\"area\",\"params\":{\"type\":\"area\",\"grid\":{\"categoryLines\":false},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"filter\":true,\"truncate\":100},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Count\"}}],\"seriesParams\":[{\"show\":true,\"type\":\"area\",\"mode\":\"stacked\",\"data\":{\"label\":\"Count\",\"id\":\"1\"},\"drawLinesBetweenPoints\":true,\"lineWidth\":2,\"showCircles\":true,\"interpolate\":\"linear\",\"valueAxis\":\"ValueAxis-1\"}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false,\"thresholdLine\":{\"show\":false,\"value\":10,\"width\":1,\"style\":\"full\",\"color\":\"#E7664C\"},\"labels\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"timeRange\":{\"from\":\"now-15m\",\"to\":\"now\"},\"useNormalizedEsInterval\":true,\"scaleMetricValues\":false,\"interval\":\"auto\",\"drop_partials\":false,\"min_doc_count\":1,\"extended_bounds\":{}}}]}"
+ }
+ }
+ }
+}
+
{
"type": "doc",
"value": {
diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts
index 1d4e51360f31..10652ce3ec4b 100644
--- a/test/functional/page_objects/discover_page.ts
+++ b/test/functional/page_objects/discover_page.ts
@@ -112,6 +112,7 @@ export function DiscoverPageProvider({ getService, getPageObjects }: FtrProvider
public async clickNewSearchButton() {
await testSubjects.click('discoverNewButton');
+ await header.waitUntilLoadingHasFinished();
}
public async clickSaveSearchButton() {
@@ -207,7 +208,7 @@ export function DiscoverPageProvider({ getService, getPageObjects }: FtrProvider
public async getAllFieldNames() {
const sidebar = await testSubjects.find('discover-sidebar');
const $ = await sidebar.parseDomContent();
- return $('.sidebar-item[attr-field]')
+ return $('.dscSidebar__item[attr-field]')
.toArray()
.map(field =>
$(field)
@@ -249,13 +250,17 @@ export function DiscoverPageProvider({ getService, getPageObjects }: FtrProvider
}
public async expectMissingFieldListItemVisualize(field: string) {
- await testSubjects.missingOrFail(`fieldVisualize-${field}`, { allowHidden: true });
+ await testSubjects.missingOrFail(`fieldVisualize-${field}`);
}
public async clickFieldListPlusFilter(field: string, value: string) {
- // this method requires the field details to be open from clickFieldListItem()
+ const plusFilterTestSubj = `plus-${field}-${value}`;
+ if (!(await testSubjects.exists(plusFilterTestSubj))) {
+ // field has to be open
+ await this.clickFieldListItem(field);
+ }
// testSubjects.find doesn't handle spaces in the data-test-subj value
- await testSubjects.click(`plus-${field}-${value}`);
+ await testSubjects.click(plusFilterTestSubj);
await header.waitUntilLoadingHasFinished();
}
diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json
index 2a28e349ace9..ae8d61769b14 100644
--- a/x-pack/.i18nrc.json
+++ b/x-pack/.i18nrc.json
@@ -16,7 +16,7 @@
"xpack.features": "plugins/features",
"xpack.fileUpload": "plugins/file_upload",
"xpack.graph": ["legacy/plugins/graph", "plugins/graph"],
- "xpack.grokDebugger": "legacy/plugins/grokdebugger",
+ "xpack.grokDebugger": "plugins/grokdebugger",
"xpack.idxMgmt": "plugins/index_management",
"xpack.indexLifecycleMgmt": "legacy/plugins/index_lifecycle_management",
"xpack.infra": "plugins/infra",
diff --git a/x-pack/index.js b/x-pack/index.js
index fb14b3dc10a4..6fab13d726fa 100644
--- a/x-pack/index.js
+++ b/x-pack/index.js
@@ -10,7 +10,6 @@ import { monitoring } from './legacy/plugins/monitoring';
import { reporting } from './legacy/plugins/reporting';
import { security } from './legacy/plugins/security';
import { tilemap } from './legacy/plugins/tilemap';
-import { grokdebugger } from './legacy/plugins/grokdebugger';
import { dashboardMode } from './legacy/plugins/dashboard_mode';
import { logstash } from './legacy/plugins/logstash';
import { beats } from './legacy/plugins/beats_management';
@@ -44,7 +43,6 @@ module.exports = function(kibana) {
spaces(kibana),
security(kibana),
tilemap(kibana),
- grokdebugger(kibana),
dashboardMode(kibana),
logstash(kibana),
beats(kibana),
diff --git a/x-pack/legacy/plugins/apm/mappings.json b/x-pack/legacy/plugins/apm/mappings.json
index 5d14ae03f9a3..1e906dd2a596 100644
--- a/x-pack/legacy/plugins/apm/mappings.json
+++ b/x-pack/legacy/plugins/apm/mappings.json
@@ -9,7 +9,7 @@
"properties": {
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -19,15 +19,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -35,7 +35,7 @@
"properties": {
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -43,15 +43,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
}
@@ -65,7 +65,7 @@
"properties": {
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -75,15 +75,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -91,15 +91,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -107,15 +107,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
}
@@ -129,7 +129,7 @@
"properties": {
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -139,15 +139,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -155,15 +155,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -171,15 +171,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
}
@@ -193,7 +193,7 @@
"properties": {
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -203,15 +203,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -219,15 +219,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -235,15 +235,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
}
@@ -257,7 +257,7 @@
"properties": {
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -267,15 +267,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -283,15 +283,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -299,15 +299,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
}
@@ -321,7 +321,7 @@
"properties": {
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -331,15 +331,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -347,15 +347,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -363,15 +363,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
}
@@ -385,7 +385,7 @@
"properties": {
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -395,15 +395,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -411,15 +411,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -427,15 +427,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
}
@@ -449,7 +449,7 @@
"properties": {
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -459,15 +459,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -475,15 +475,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
},
@@ -491,15 +491,15 @@
"properties": {
"composite": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"name": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
},
"version": {
"type": "keyword",
- "ignore_above": 256
+ "ignore_above": 1024
}
}
}
diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_lens.ts b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_lens.ts
index 60026adc0998..2985a68cf855 100644
--- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_lens.ts
+++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_lens.ts
@@ -5,8 +5,8 @@
*/
import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common';
-import { TimeRange } from 'src/plugins/data/public';
-import { EmbeddableInput } from 'src/legacy/core_plugins/embeddable_api/public/np_ready/public';
+import { TimeRange, Filter as DataFilter } from 'src/plugins/data/public';
+import { EmbeddableInput } from 'src/plugins/embeddable/public';
import { getQueryFilters } from '../../../public/lib/build_embeddable_filters';
import { Filter, TimeRange as TimeRangeArg } from '../../../types';
import {
@@ -15,7 +15,6 @@ import {
EmbeddableExpression,
} from '../../expression_types';
import { getFunctionHelp } from '../../../i18n';
-import { Filter as DataFilter } from '../../../../../../../src/plugins/data/public';
interface Arguments {
id: string;
diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_map.ts b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_map.ts
index 78240eee7ce1..4b045b0c5edc 100644
--- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_map.ts
+++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_map.ts
@@ -5,8 +5,8 @@
*/
import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common';
-import { TimeRange } from 'src/plugins/data/public';
-import { EmbeddableInput } from 'src/legacy/core_plugins/embeddable_api/public/np_ready/public';
+import { TimeRange, Filter as DataFilter } from 'src/plugins/data/public';
+import { EmbeddableInput } from 'src/plugins/embeddable/public';
import { getQueryFilters } from '../../../public/lib/build_embeddable_filters';
import { Filter, MapCenter, TimeRange as TimeRangeArg } from '../../../types';
import {
@@ -15,7 +15,6 @@ import {
EmbeddableExpression,
} from '../../expression_types';
import { getFunctionHelp } from '../../../i18n';
-import { Filter as DataFilter } from '../../../../../../../src/plugins/data/public';
interface Arguments {
id: string;
diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx
index 3cdb6eb46022..817be6e144fc 100644
--- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx
+++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx
@@ -14,7 +14,6 @@ import {
EmbeddablePanel,
EmbeddableFactoryNotFoundError,
} from '../../../../../../../src/plugins/embeddable/public';
-import { start } from '../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public/legacy';
import { EmbeddableExpression } from '../../expression_types/embeddable';
import { RendererStrings } from '../../../i18n';
import { getSavedObjectFinder } from '../../../../../../../src/plugins/saved_objects/public';
@@ -39,8 +38,8 @@ const renderEmbeddable = (embeddableObject: IEmbeddable, domNode: HTMLElement) =
({
const uniqueId = handlers.getElementId();
if (!embeddablesRegistry[uniqueId]) {
- const factory = Array.from(start.getEmbeddableFactories()).find(
+ const factory = Array.from(npStart.plugins.embeddable.getEmbeddableFactories()).find(
embeddableFactory => embeddableFactory.type === embeddableType
) as EmbeddableFactory;
diff --git a/x-pack/legacy/plugins/canvas/public/components/embeddable_flyout/flyout.tsx b/x-pack/legacy/plugins/canvas/public/components/embeddable_flyout/flyout.tsx
index 576c7c4794b0..08cd3084c35c 100644
--- a/x-pack/legacy/plugins/canvas/public/components/embeddable_flyout/flyout.tsx
+++ b/x-pack/legacy/plugins/canvas/public/components/embeddable_flyout/flyout.tsx
@@ -5,13 +5,12 @@
*/
import React from 'react';
-
+import { npStart } from 'ui/new_platform';
import { EuiFlyout, EuiFlyoutHeader, EuiFlyoutBody, EuiTitle } from '@elastic/eui';
import {
SavedObjectFinderUi,
SavedObjectMetaData,
} from '../../../../../../../src/plugins/saved_objects/public/';
-import { start } from '../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public/legacy';
import { ComponentStrings } from '../../../i18n';
import { CoreStart } from '../../../../../../../src/core/public';
@@ -27,7 +26,7 @@ export interface Props {
export class AddEmbeddableFlyout extends React.Component {
onAddPanel = (id: string, savedObjectType: string, name: string) => {
- const embeddableFactories = start.getEmbeddableFactories();
+ const embeddableFactories = npStart.plugins.embeddable.getEmbeddableFactories();
// Find the embeddable type from the saved object type
const found = Array.from(embeddableFactories).find(embeddableFactory => {
@@ -43,7 +42,7 @@ export class AddEmbeddableFlyout extends React.Component {
};
render() {
- const embeddableFactories = start.getEmbeddableFactories();
+ const embeddableFactories = npStart.plugins.embeddable.getEmbeddableFactories();
const availableSavedObjects = Array.from(embeddableFactories)
.filter(factory => {
diff --git a/x-pack/legacy/plugins/grokdebugger/index.js b/x-pack/legacy/plugins/grokdebugger/index.js
deleted file mode 100644
index 7803aed739b9..000000000000
--- a/x-pack/legacy/plugins/grokdebugger/index.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { resolve } from 'path';
-import { PLUGIN } from './common/constants';
-import { registerGrokdebuggerRoutes } from './server/routes/api/grokdebugger';
-import { registerLicenseChecker } from './server/lib/register_license_checker';
-
-export const grokdebugger = kibana =>
- new kibana.Plugin({
- id: PLUGIN.ID,
- publicDir: resolve(__dirname, 'public'),
- require: ['kibana', 'elasticsearch', 'xpack_main'],
- configPrefix: 'xpack.grokdebugger',
- config(Joi) {
- return Joi.object({
- enabled: Joi.boolean().default(true),
- }).default();
- },
- uiExports: {
- devTools: ['plugins/grokdebugger/register'],
- home: ['plugins/grokdebugger/register_feature'],
- },
- init: server => {
- registerLicenseChecker(server);
- registerGrokdebuggerRoutes(server);
- },
- });
diff --git a/x-pack/legacy/plugins/grokdebugger/public/register.js b/x-pack/legacy/plugins/grokdebugger/public/register.js
deleted file mode 100644
index 74679d65e52d..000000000000
--- a/x-pack/legacy/plugins/grokdebugger/public/register.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { i18n } from '@kbn/i18n';
-import { xpackInfo } from 'plugins/xpack_main/services/xpack_info';
-import { npSetup, npStart } from 'ui/new_platform';
-
-npSetup.plugins.devTools.register({
- order: 6,
- title: i18n.translate('xpack.grokDebugger.displayName', {
- defaultMessage: 'Grok Debugger',
- }),
- id: 'grokdebugger',
- enableRouting: false,
- disabled: !xpackInfo.get('features.grokdebugger.enableLink', false),
- tooltipContent: xpackInfo.get('features.grokdebugger.message'),
- async mount(context, { element }) {
- const licenseCheck = {
- showPage: xpackInfo.get('features.grokdebugger.enableLink'),
- message: xpackInfo.get('features.grokdebugger.message'),
- };
- if (!licenseCheck.showPage) {
- npStart.core.notifications.toasts.addDanger(licenseCheck.message);
- window.location.hash = '/dev_tools';
- return () => {};
- }
- const { renderApp } = await import('./render_app');
- return renderApp(element, npStart);
- },
-});
diff --git a/x-pack/legacy/plugins/grokdebugger/public/register_feature.ts b/x-pack/legacy/plugins/grokdebugger/public/register_feature.ts
deleted file mode 100644
index 97d2e53ce783..000000000000
--- a/x-pack/legacy/plugins/grokdebugger/public/register_feature.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { i18n } from '@kbn/i18n';
-import { npSetup } from 'ui/new_platform';
-import { FeatureCatalogueCategory } from '../../../../../src/plugins/home/public';
-
-const {
- plugins: { home },
-} = npSetup;
-
-home.featureCatalogue.register({
- id: 'grokdebugger',
- title: i18n.translate('xpack.grokDebugger.registryProviderTitle', {
- defaultMessage: '{grokLogParsingTool} Debugger',
- values: {
- grokLogParsingTool: 'Grok',
- },
- }),
- description: i18n.translate('xpack.grokDebugger.registryProviderDescription', {
- defaultMessage:
- 'Simulate and debug {grokLogParsingTool} patterns for data transformation on ingestion.',
- values: {
- grokLogParsingTool: 'grok',
- },
- }),
- icon: 'grokApp',
- path: '/app/kibana#/dev_tools/grokdebugger',
- showOnHomePage: false,
- category: FeatureCatalogueCategory.ADMIN,
-});
diff --git a/x-pack/legacy/plugins/grokdebugger/server/lib/call_with_request_factory/call_with_request_factory.js b/x-pack/legacy/plugins/grokdebugger/server/lib/call_with_request_factory/call_with_request_factory.js
deleted file mode 100644
index 7359a831994f..000000000000
--- a/x-pack/legacy/plugins/grokdebugger/server/lib/call_with_request_factory/call_with_request_factory.js
+++ /dev/null
@@ -1,18 +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 { once } from 'lodash';
-
-const callWithRequest = once(server => {
- const cluster = server.plugins.elasticsearch.getCluster('data');
- return cluster.callWithRequest;
-});
-
-export const callWithRequestFactory = (server, request) => {
- return (...args) => {
- return callWithRequest(server)(request, ...args);
- };
-};
diff --git a/x-pack/legacy/plugins/grokdebugger/server/lib/check_license/__tests__/check_license.js b/x-pack/legacy/plugins/grokdebugger/server/lib/check_license/__tests__/check_license.js
deleted file mode 100644
index 7e32d68a67ec..000000000000
--- a/x-pack/legacy/plugins/grokdebugger/server/lib/check_license/__tests__/check_license.js
+++ /dev/null
@@ -1,90 +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 expect from '@kbn/expect';
-import { set } from 'lodash';
-import { checkLicense } from '../check_license';
-
-describe('check_license', function() {
- let mockLicenseInfo;
- beforeEach(() => (mockLicenseInfo = {}));
-
- describe('license information is undefined', () => {
- beforeEach(() => (mockLicenseInfo = undefined));
-
- it('should set enableLink to false', () => {
- expect(checkLicense(mockLicenseInfo).enableLink).to.be(false);
- });
-
- it('should set enableAPIRoute to false', () => {
- expect(checkLicense(mockLicenseInfo).enableAPIRoute).to.be(false);
- });
-
- it('should set a message', () => {
- expect(checkLicense(mockLicenseInfo).message).to.not.be(undefined);
- });
- });
-
- describe('license information is not available', () => {
- beforeEach(() => (mockLicenseInfo.isAvailable = () => false));
-
- it('should set enableLink to false', () => {
- expect(checkLicense(mockLicenseInfo).enableLink).to.be(false);
- });
-
- it('should set enableAPIRoute to false', () => {
- expect(checkLicense(mockLicenseInfo).enableAPIRoute).to.be(false);
- });
-
- it('should set a message', () => {
- expect(checkLicense(mockLicenseInfo).message).to.not.be(undefined);
- });
- });
-
- describe('license information is available', () => {
- beforeEach(
- () =>
- (mockLicenseInfo = {
- isAvailable: () => true,
- license: {
- getType: () => 'foobar',
- },
- })
- );
-
- describe('& license is active', () => {
- beforeEach(() => set(mockLicenseInfo, 'license.isActive', () => true));
-
- it('should set enableLink to true', () => {
- expect(checkLicense(mockLicenseInfo).enableLink).to.be(true);
- });
-
- it('should set enableAPIRoute to true', () => {
- expect(checkLicense(mockLicenseInfo).enableAPIRoute).to.be(true);
- });
-
- it('should NOT set a message', () => {
- expect(checkLicense(mockLicenseInfo).message).to.be(undefined);
- });
- });
-
- describe('& license is expired', () => {
- beforeEach(() => set(mockLicenseInfo, 'license.isActive', () => false));
-
- it('should set enableLink to false', () => {
- expect(checkLicense(mockLicenseInfo).enableLink).to.be(false);
- });
-
- it('should set enableAPIRoute to false', () => {
- expect(checkLicense(mockLicenseInfo).enableAPIRoute).to.be(false);
- });
-
- it('should set a message', () => {
- expect(checkLicense(mockLicenseInfo).message).to.not.be(undefined);
- });
- });
- });
-});
diff --git a/x-pack/legacy/plugins/grokdebugger/server/lib/check_license/check_license.js b/x-pack/legacy/plugins/grokdebugger/server/lib/check_license/check_license.js
deleted file mode 100644
index c7a8d2bbca05..000000000000
--- a/x-pack/legacy/plugins/grokdebugger/server/lib/check_license/check_license.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { i18n } from '@kbn/i18n';
-
-export function checkLicense(xpackLicenseInfo) {
- // If, for some reason, we cannot get the license information
- // from Elasticsearch, assume worst case and disable the Watcher UI
- if (!xpackLicenseInfo || !xpackLicenseInfo.isAvailable()) {
- return {
- enableLink: false,
- enableAPIRoute: false,
- message: i18n.translate('xpack.grokDebugger.unavailableLicenseInformationMessage', {
- defaultMessage:
- 'You cannot use the {grokLogParsingTool} Debugger because license information is not available at this time.',
- values: {
- grokLogParsingTool: 'Grok',
- },
- }),
- };
- }
-
- const isLicenseActive = xpackLicenseInfo.license.isActive();
- const licenseType = xpackLicenseInfo.license.getType();
-
- // License is not valid
- if (!isLicenseActive) {
- return {
- enableLink: false,
- enableAPIRoute: false,
- message: i18n.translate('xpack.grokDebugger.licenseHasExpiredMessage', {
- defaultMessage:
- 'You cannot use the {grokLogParsingTool} Debugger because your {licenseType} license has expired.',
- values: {
- licenseType,
- grokLogParsingTool: 'Grok',
- },
- }),
- };
- }
-
- // License is valid and active
- return {
- enableLink: true,
- enableAPIRoute: true,
- };
-}
diff --git a/x-pack/legacy/plugins/grokdebugger/server/lib/error_wrappers/wrap_es_error.js b/x-pack/legacy/plugins/grokdebugger/server/lib/error_wrappers/wrap_es_error.js
deleted file mode 100644
index dfcd4e3b1e17..000000000000
--- a/x-pack/legacy/plugins/grokdebugger/server/lib/error_wrappers/wrap_es_error.js
+++ /dev/null
@@ -1,18 +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 Boom from 'boom';
-
-/**
- * Wraps ES errors into a Boom error response and returns it
- * This also handles the permissions issue gracefully
- *
- * @param err Object ES error
- * @return Object Boom error response
- */
-export function wrapEsError(err) {
- return Boom.boomify(err, { statusCode: err.statusCode });
-}
diff --git a/x-pack/legacy/plugins/grokdebugger/server/lib/license_pre_routing_factory/__tests__/license_pre_routing_factory.js b/x-pack/legacy/plugins/grokdebugger/server/lib/license_pre_routing_factory/__tests__/license_pre_routing_factory.js
deleted file mode 100644
index 135317f05077..000000000000
--- a/x-pack/legacy/plugins/grokdebugger/server/lib/license_pre_routing_factory/__tests__/license_pre_routing_factory.js
+++ /dev/null
@@ -1,64 +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 expect from '@kbn/expect';
-import Boom from 'boom';
-import { licensePreRoutingFactory } from '../license_pre_routing_factory';
-
-describe('license_pre_routing_factory', () => {
- describe('#grokDebuggerFeaturePreRoutingFactory', () => {
- let mockServer;
- let mockLicenseCheckResults;
-
- beforeEach(() => {
- mockServer = {
- plugins: {
- xpack_main: {
- info: {
- feature: () => ({
- getLicenseCheckResults: () => mockLicenseCheckResults,
- }),
- },
- },
- },
- };
- });
-
- describe('isAvailable is false', () => {
- beforeEach(() => {
- mockLicenseCheckResults = {
- isAvailable: false,
- };
- });
-
- it('replies with 403', async () => {
- const licensePreRouting = licensePreRoutingFactory(mockServer);
- const stubRequest = {};
- expect(() => licensePreRouting(stubRequest)).to.throwException(response => {
- expect(response).to.be.an(Error);
- expect(response.isBoom).to.be(true);
- expect(response.output.statusCode).to.be(403);
- });
- });
- });
-
- describe('isAvailable is true', () => {
- beforeEach(() => {
- mockLicenseCheckResults = {
- isAvailable: true,
- };
- });
-
- it('replies with forbidden', async () => {
- const licensePreRouting = licensePreRoutingFactory(mockServer);
- const stubRequest = {};
- expect(() => licensePreRouting(stubRequest)).to.throwException(response => {
- expect(response).to.eql(Boom.forbidden());
- });
- });
- });
- });
-});
diff --git a/x-pack/legacy/plugins/grokdebugger/server/lib/license_pre_routing_factory/license_pre_routing_factory.js b/x-pack/legacy/plugins/grokdebugger/server/lib/license_pre_routing_factory/license_pre_routing_factory.js
deleted file mode 100644
index 88c844de3e2c..000000000000
--- a/x-pack/legacy/plugins/grokdebugger/server/lib/license_pre_routing_factory/license_pre_routing_factory.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import Boom from 'boom';
-import { PLUGIN } from '../../../common/constants';
-
-export const licensePreRoutingFactory = server => {
- const xpackMainPlugin = server.plugins.xpack_main;
-
- // License checking and enable/disable logic
- function licensePreRouting() {
- const licenseCheckResults = xpackMainPlugin.info.feature(PLUGIN.ID).getLicenseCheckResults();
- if (!licenseCheckResults.enableAPIRoute) {
- throw Boom.forbidden(licenseCheckResults.message);
- }
-
- return null;
- }
-
- return licensePreRouting;
-};
diff --git a/x-pack/legacy/plugins/grokdebugger/server/lib/register_license_checker/index.js b/x-pack/legacy/plugins/grokdebugger/server/lib/register_license_checker/index.js
deleted file mode 100644
index 7b0f97c38d12..000000000000
--- a/x-pack/legacy/plugins/grokdebugger/server/lib/register_license_checker/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-export { registerLicenseChecker } from './register_license_checker';
diff --git a/x-pack/legacy/plugins/grokdebugger/server/lib/register_license_checker/register_license_checker.js b/x-pack/legacy/plugins/grokdebugger/server/lib/register_license_checker/register_license_checker.js
deleted file mode 100644
index ee9a9a3ebdec..000000000000
--- a/x-pack/legacy/plugins/grokdebugger/server/lib/register_license_checker/register_license_checker.js
+++ /dev/null
@@ -1,21 +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 { mirrorPluginStatus } from '../../../../../server/lib/mirror_plugin_status';
-import { checkLicense } from '../check_license';
-import { PLUGIN } from '../../../common/constants';
-
-export function registerLicenseChecker(server) {
- const xpackMainPlugin = server.plugins.xpack_main;
- const grokdebuggerPlugin = server.plugins[PLUGIN.ID];
-
- mirrorPluginStatus(xpackMainPlugin, grokdebuggerPlugin);
- xpackMainPlugin.status.once('green', () => {
- // Register a function that is called whenever the xpack info changes,
- // to re-compute the license check results for this plugin
- xpackMainPlugin.info.feature(PLUGIN.ID).registerLicenseCheckResultsGenerator(checkLicense);
- });
-}
diff --git a/x-pack/legacy/plugins/grokdebugger/server/routes/api/grokdebugger/register_grok_simulate_route.js b/x-pack/legacy/plugins/grokdebugger/server/routes/api/grokdebugger/register_grok_simulate_route.js
deleted file mode 100644
index 14ea1e7acb66..000000000000
--- a/x-pack/legacy/plugins/grokdebugger/server/routes/api/grokdebugger/register_grok_simulate_route.js
+++ /dev/null
@@ -1,41 +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 { wrapEsError } from '../../../lib/error_wrappers';
-import { callWithRequestFactory } from '../../../lib/call_with_request_factory';
-import { GrokdebuggerRequest } from '../../../models/grokdebugger_request';
-import { GrokdebuggerResponse } from '../../../models/grokdebugger_response';
-import { licensePreRoutingFactory } from '../../../lib/license_pre_routing_factory';
-
-function simulateGrok(callWithRequest, ingestJson) {
- return callWithRequest('ingest.simulate', {
- body: ingestJson,
- });
-}
-
-export function registerGrokSimulateRoute(server) {
- const licensePreRouting = licensePreRoutingFactory(server);
-
- server.route({
- path: '/api/grokdebugger/simulate',
- method: 'POST',
- handler: request => {
- const callWithRequest = callWithRequestFactory(server, request);
- const grokdebuggerRequest = GrokdebuggerRequest.fromDownstreamJSON(request.payload);
- return simulateGrok(callWithRequest, grokdebuggerRequest.upstreamJSON)
- .then(simulateResponseFromES => {
- const grokdebuggerResponse = GrokdebuggerResponse.fromUpstreamJSON(
- simulateResponseFromES
- );
- return { grokdebuggerResponse };
- })
- .catch(e => wrapEsError(e));
- },
- config: {
- pre: [licensePreRouting],
- },
- });
-}
diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/embeddable/embeddable_factory.ts b/x-pack/legacy/plugins/lens/public/editor_frame_service/embeddable/embeddable_factory.ts
index 2bde698e2356..1caea1b4b728 100644
--- a/x-pack/legacy/plugins/lens/public/editor_frame_service/embeddable/embeddable_factory.ts
+++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/embeddable/embeddable_factory.ts
@@ -22,7 +22,7 @@ import {
ErrorEmbeddable,
EmbeddableInput,
IContainer,
-} from '../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public';
+} from '../../../../../../../src/plugins/embeddable/public';
import { Embeddable } from './embeddable';
import { SavedObjectIndexStore, DOC_TYPE } from '../../persistence';
import { getEditPath } from '../../../../../../plugins/lens/common';
diff --git a/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable_factory.ts b/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable_factory.ts
index ddb937dd9892..b9cb66f83128 100644
--- a/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable_factory.ts
+++ b/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable_factory.ts
@@ -11,14 +11,13 @@ import { i18n } from '@kbn/i18n';
import { npSetup, npStart } from 'ui/new_platform';
import { SavedObjectLoader } from 'src/plugins/saved_objects/public';
import { IIndexPattern } from 'src/plugins/data/public';
+import { MapEmbeddable, MapEmbeddableInput } from './map_embeddable';
+import { getIndexPatternService } from '../kibana_services';
import {
EmbeddableFactory,
ErrorEmbeddable,
IContainer,
-} from '../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public';
-import { setup } from '../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public/legacy';
-import { MapEmbeddable, MapEmbeddableInput } from './map_embeddable';
-import { getIndexPatternService } from '../kibana_services';
+} from '../../../../../../src/plugins/embeddable/public';
import { createMapPath, MAP_SAVED_OBJECT_TYPE, APP_ICON } from '../../common/constants';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
@@ -171,4 +170,7 @@ export class MapEmbeddableFactory extends EmbeddableFactory {
}
}
-setup.registerEmbeddableFactory(MAP_SAVED_OBJECT_TYPE, new MapEmbeddableFactory());
+npSetup.plugins.embeddable.registerEmbeddableFactory(
+ MAP_SAVED_OBJECT_TYPE,
+ new MapEmbeddableFactory()
+);
diff --git a/x-pack/legacy/plugins/maps/server/routes.js b/x-pack/legacy/plugins/maps/server/routes.js
index 6aacfdc41aee..20e022001577 100644
--- a/x-pack/legacy/plugins/maps/server/routes.js
+++ b/x-pack/legacy/plugins/maps/server/routes.js
@@ -44,6 +44,7 @@ export function initRoutes(server, licenseUid) {
fileApiUrl: mapConfig.emsFileApiUrl,
tileApiUrl: mapConfig.emsTileApiUrl,
landingPageUrl: mapConfig.emsLandingPageUrl,
+ fetchFunction: fetch,
});
emsClient.addQueryParams({ license: licenseUid });
} else {
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/layouts/preserve_layout.css b/x-pack/legacy/plugins/reporting/export_types/common/layouts/preserve_layout.css
index 2c203e507260..88e38d55e578 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/layouts/preserve_layout.css
+++ b/x-pack/legacy/plugins/reporting/export_types/common/layouts/preserve_layout.css
@@ -34,7 +34,7 @@ filter-bar,
/* hide unusable controls */
discover-app .dscTimechart,
-discover-app .sidebar-container,
+discover-app .dscSidebar__container,
discover-app .kbnCollapsibleSidebar__collapseButton,
discover-app navbar[name=discover-search],
discover-app .discover-table-footer {
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/layouts/print.css b/x-pack/legacy/plugins/reporting/export_types/common/layouts/print.css
index b5c9861208b7..ddd280c7b3f2 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/layouts/print.css
+++ b/x-pack/legacy/plugins/reporting/export_types/common/layouts/print.css
@@ -33,7 +33,7 @@ filter-bar,
/* hide unusable controls */
discover-app .dscTimechart,
-discover-app .sidebar-container,
+discover-app .dscSidebar__container,
discover-app .kbnCollapsibleSidebar__collapseButton,
discover-app navbar[name="discover-search"],
discover-app .discover-table-footer {
diff --git a/x-pack/legacy/plugins/siem/cypress/objects/rule.ts b/x-pack/legacy/plugins/siem/cypress/objects/rule.ts
index 37c325c3b803..ce920aeb957a 100644
--- a/x-pack/legacy/plugins/siem/cypress/objects/rule.ts
+++ b/x-pack/legacy/plugins/siem/cypress/objects/rule.ts
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-export const totalNumberOfPrebuiltRules = 92;
+export const totalNumberOfPrebuiltRules = 130;
interface Mitre {
tactic: string;
diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx
index a3c4a655a493..c7e368da1338 100644
--- a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx
@@ -8,9 +8,9 @@ import { EuiLink, EuiText } from '@elastic/eui';
import React, { useEffect, useState } from 'react';
import { createPortalNode, InPortal } from 'react-reverse-portal';
import styled, { css } from 'styled-components';
+import { npStart } from 'ui/new_platform';
-import { EmbeddablePanel } from '../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public';
-import { start } from '../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public/legacy';
+import { EmbeddablePanel } from '../../../../../../../src/plugins/embeddable/public';
import { DEFAULT_INDEX_KEY } from '../../../common/constants';
import { getIndexPatternTitleIdMapping } from '../../hooks/api/helpers';
import { useIndexPatterns } from '../../hooks/use_index_patterns';
@@ -198,8 +198,8 @@ export const EmbeddedMapComponent = ({
data-test-subj="embeddable-panel"
embeddable={embeddable}
getActions={services.uiActions.getTriggerCompatibleActions}
- getEmbeddableFactory={start.getEmbeddableFactory}
- getAllEmbeddableFactories={start.getEmbeddableFactories}
+ getEmbeddableFactory={npStart.plugins.embeddable.getEmbeddableFactory}
+ getAllEmbeddableFactories={npStart.plugins.embeddable.getEmbeddableFactories}
notifications={services.notifications}
overlays={services.overlays}
inspector={services.inspector}
diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map_helpers.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map_helpers.tsx
index 4b32fd8299ef..56211c9ff893 100644
--- a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map_helpers.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map_helpers.tsx
@@ -8,14 +8,13 @@ import uuid from 'uuid';
import React from 'react';
import { OutPortal, PortalNode } from 'react-reverse-portal';
import minimatch from 'minimatch';
-import { ViewMode } from '../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public';
import { IndexPatternMapping, SetQuery } from './types';
import { getLayerList } from './map_config';
import { MAP_SAVED_OBJECT_TYPE } from '../../../../../../plugins/maps/public';
import { MapEmbeddable, RenderTooltipContentParams } from '../../../../maps/public';
import * as i18n from './translations';
import { Query, Filter } from '../../../../../../../src/plugins/data/public';
-import { EmbeddableStart } from '../../../../../../../src/plugins/embeddable/public';
+import { EmbeddableStart, ViewMode } from '../../../../../../../src/plugins/embeddable/public';
import { IndexPatternSavedObject } from '../../hooks/types';
/**
diff --git a/x-pack/legacy/plugins/siem/public/components/filter_popover/index.tsx b/x-pack/legacy/plugins/siem/public/components/filter_popover/index.tsx
index 0c4497f7630c..3c01ec18a879 100644
--- a/x-pack/legacy/plugins/siem/public/components/filter_popover/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/filter_popover/index.tsx
@@ -76,6 +76,7 @@ export const FilterPopoverComponent = ({
numFilters={options.length}
hasActiveFilters={selectedOptions.length > 0}
numActiveFilters={selectedOptions.length}
+ aria-label={buttonLabel}
>
{buttonLabel}
diff --git a/x-pack/legacy/plugins/siem/public/components/link_icon/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/link_icon/__snapshots__/index.test.tsx.snap
index c5086c8cde28..986e9161c519 100644
--- a/x-pack/legacy/plugins/siem/public/components/link_icon/__snapshots__/index.test.tsx.snap
+++ b/x-pack/legacy/plugins/siem/public/components/link_icon/__snapshots__/index.test.tsx.snap
@@ -2,6 +2,7 @@
exports[`LinkIcon it renders 1`] = `
{children} )<
@@ -52,7 +53,17 @@ export interface LinkIconProps extends LinkProps {
}
export const LinkIcon = React.memo(
- ({ children, color, disabled, href, iconSide = 'left', iconSize = 's', iconType, onClick }) => (
+ ({
+ children,
+ color,
+ disabled,
+ href,
+ iconSide = 'left',
+ iconSize = 's',
+ iconType,
+ onClick,
+ ariaLabel,
+ }) => (
(
href={href}
iconSide={iconSide}
onClick={onClick}
+ aria-label={ariaLabel ?? children}
>
{children}
diff --git a/x-pack/legacy/plugins/siem/public/components/links/index.tsx b/x-pack/legacy/plugins/siem/public/components/links/index.tsx
index 14dc5e7999a6..62a67af6e08b 100644
--- a/x-pack/legacy/plugins/siem/public/components/links/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/links/index.tsx
@@ -23,12 +23,13 @@ import {
import { FlowTarget, FlowTargetSourceDest } from '../../graphql/types';
import { useUiSetting$ } from '../../lib/kibana';
import { IP_REPUTATION_LINKS_SETTING } from '../../../common/constants';
-import * as i18n from '../page/network/ip_overview/translations';
import { isUrlInvalid } from '../../pages/detection_engine/rules/components/step_about_rule/helpers';
import { ExternalLinkIcon } from '../external_link_icon';
import { navTabs } from '../../pages/home/home_navigations';
import { useGetUrlSearch } from '../navigation/use_get_url_search';
+import * as i18n from './translations';
+
export const DEFAULT_NUMBER_OF_LINK = 5;
// Internal Links
@@ -88,16 +89,18 @@ const IPDetailsLinkComponent: React.FC<{
export const IPDetailsLink = React.memo(IPDetailsLinkComponent);
-const CaseDetailsLinkComponent: React.FC<{ children?: React.ReactNode; detailName: string }> = ({
- children,
- detailName,
-}) => {
+const CaseDetailsLinkComponent: React.FC<{
+ children?: React.ReactNode;
+ detailName: string;
+ title?: string;
+}> = ({ children, detailName, title }) => {
const search = useGetUrlSearch(navTabs.case);
return (
{children ? children : detailName}
diff --git a/x-pack/legacy/plugins/siem/public/components/links/translations.ts b/x-pack/legacy/plugins/siem/public/components/links/translations.ts
new file mode 100644
index 000000000000..bed867cd5bf5
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/links/translations.ts
@@ -0,0 +1,15 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { i18n } from '@kbn/i18n';
+
+export * from '../page/network/ip_overview/translations';
+
+export const CASE_DETAILS_LINK_ARIA = (detailName: string) =>
+ i18n.translate('xpack.siem.case.caseTable.caseDetailsLinkAria', {
+ values: { detailName },
+ defaultMessage: 'click to visit case with title {detailName}',
+ });
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
index 19e884e32639..330e7f83b5b2 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
@@ -18,6 +18,7 @@ const Popover = React.memo(
return (
> => [
{
- description: i18n.DELETE,
+ description: i18n.DELETE_CASE,
icon: 'trash',
- name: i18n.DELETE,
+ name: i18n.DELETE_CASE,
onClick: deleteCaseOnClick,
type: 'icon',
'data-test-subj': 'action-delete',
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/columns.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/columns.tsx
index f4cfac49f72e..f757fd33a93a 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/columns.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/columns.tsx
@@ -46,7 +46,9 @@ export const getCasesColumns = (
render: (theCase: Case) => {
if (theCase.id != null && theCase.title != null) {
const caseDetailsLinkComponent = (
- {theCase.title}
+
+ {theCase.title}
+
);
return theCase.status === 'open' ? (
caseDetailsLinkComponent
@@ -184,6 +186,7 @@ const ServiceNowColumn: React.FC = ({ theCase }) => {
data-test-subj={`case-table-column-external`}
href={theCase.externalService?.externalUrl}
target="_blank"
+ aria-label={i18n.SERVICENOW_LINK_ARIA}
>
{theCase.externalService?.externalTitle}
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/translations.ts b/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/translations.ts
index e8459454576e..1bee96bc23ff 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/translations.ts
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/translations.ts
@@ -59,9 +59,11 @@ export const CLOSED_CASES = i18n.translate('xpack.siem.case.caseTable.closedCase
export const CLOSED = i18n.translate('xpack.siem.case.caseTable.closed', {
defaultMessage: 'Closed',
});
+
export const DELETE = i18n.translate('xpack.siem.case.caseTable.delete', {
defaultMessage: 'Delete',
});
+
export const REQUIRES_UPDATE = i18n.translate('xpack.siem.case.caseTable.requiresUpdate', {
defaultMessage: ' requires update',
});
@@ -76,3 +78,7 @@ export const NOT_PUSHED = i18n.translate('xpack.siem.case.caseTable.notPushed',
export const REFRESH = i18n.translate('xpack.siem.case.caseTable.refreshTitle', {
defaultMessage: 'Refresh',
});
+
+export const SERVICENOW_LINK_ARIA = i18n.translate('xpack.siem.case.caseTable.serviceNowLinkAria', {
+ defaultMessage: 'click to view the incident on servicenow',
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/configure_cases/button.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/configure_cases/button.tsx
index 9cfc51da22e8..b0bea83148bd 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/configure_cases/button.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/configure_cases/button.tsx
@@ -31,6 +31,7 @@ const ConfigureCaseButtonComponent: React.FC = ({
href={getConfigureCasesUrl(urlSearch)}
iconType="controlsHorizontal"
isDisabled={isDisabled}
+ aria-label={label}
>
{label}
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/configure_cases/index.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/configure_cases/index.tsx
index 241b0b123027..b8cf5a388080 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/configure_cases/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/configure_cases/index.tsx
@@ -298,7 +298,7 @@ const ConfigureCasesComponent: React.FC = ({ userC
iconType="cross"
isDisabled={isLoadingAny}
isLoading={persistLoading}
- aria-label="Cancel"
+ aria-label={i18n.CANCEL}
href={getCaseUrl(search)}
>
{i18n.CANCEL}
@@ -309,7 +309,7 @@ const ConfigureCasesComponent: React.FC = ({ userC
fill
color="secondary"
iconType="save"
- aria-label="Save"
+ aria-label={i18n.SAVE_CHANGES}
isDisabled={isLoadingAny}
isLoading={persistLoading}
onClick={handleSubmit}
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/property_actions/index.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/property_actions/index.tsx
index 0e7a41edace0..6b8e00921abc 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/property_actions/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/property_actions/index.tsx
@@ -7,6 +7,8 @@
import React, { useCallback, useState } from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiPopover, EuiButtonIcon, EuiButtonEmpty } from '@elastic/eui';
+import * as i18n from './translations';
+
export interface PropertyActionButtonProps {
disabled?: boolean;
onClick: () => void;
@@ -57,10 +59,11 @@ export const PropertyActions = React.memo(({ propertyActio
diff --git a/x-pack/legacy/plugins/grokdebugger/server/lib/call_with_request_factory/index.js b/x-pack/legacy/plugins/siem/public/pages/case/components/property_actions/translations.ts
similarity index 57%
rename from x-pack/legacy/plugins/grokdebugger/server/lib/call_with_request_factory/index.js
rename to x-pack/legacy/plugins/siem/public/pages/case/components/property_actions/translations.ts
index 787814d87dff..4d7e15a76739 100644
--- a/x-pack/legacy/plugins/grokdebugger/server/lib/call_with_request_factory/index.js
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/property_actions/translations.ts
@@ -4,4 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
-export { callWithRequestFactory } from './call_with_request_factory';
+import { i18n } from '@kbn/i18n';
+
+export const ACTIONS_ARIA = i18n.translate('xpack.siem.case.caseView.editActionsLinkAria', {
+ defaultMessage: 'click to see all actions',
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/tag_list/index.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/tag_list/index.tsx
index 7c456d27aced..f7d890ca60b1 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/tag_list/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/tag_list/index.tsx
@@ -17,7 +17,7 @@ import {
EuiLoadingSpinner,
} from '@elastic/eui';
import styled, { css } from 'styled-components';
-import * as i18n from '../../translations';
+import * as i18n from './translations';
import { Form, useForm } from '../../../../shared_imports';
import { schema } from './schema';
import { CommonUseField } from '../create';
@@ -66,7 +66,7 @@ export const TagList = React.memo(
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/tag_list/translations.ts b/x-pack/legacy/plugins/siem/public/pages/case/components/tag_list/translations.ts
new file mode 100644
index 000000000000..f7f215248dad
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/tag_list/translations.ts
@@ -0,0 +1,13 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { i18n } from '@kbn/i18n';
+
+export * from '../../translations';
+
+export const EDIT_TAGS_ARIA = i18n.translate('xpack.siem.case.caseView.editTagsLinkAria', {
+ defaultMessage: 'click to edit tags',
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/user_list/index.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/user_list/index.tsx
index 914bbe1d3f38..579e8e48fa14 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/user_list/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/user_list/index.tsx
@@ -5,6 +5,8 @@
*/
import React, { useCallback } from 'react';
+import { isEmpty } from 'lodash/fp';
+
import {
EuiButtonIcon,
EuiText,
@@ -15,8 +17,11 @@ import {
EuiLoadingSpinner,
EuiToolTip,
} from '@elastic/eui';
+
import styled, { css } from 'styled-components';
+
import { ElasticUser } from '../../../../containers/case/types';
+import * as i18n from './translations';
interface UserListProps {
email: {
@@ -50,7 +55,7 @@ const renderUsers = (
- {fullName ?? username}}>
+ {fullName ? fullName : username ?? ''}}>
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/user_list/translations.ts b/x-pack/legacy/plugins/siem/public/pages/case/components/user_list/translations.ts
new file mode 100644
index 000000000000..4d50d11f3910
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/user_list/translations.ts
@@ -0,0 +1,13 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { i18n } from '@kbn/i18n';
+
+export const SEND_EMAIL_ARIA = (user: string) =>
+ i18n.translate('xpack.siem.case.caseView.sendEmalLinkAria', {
+ values: { user },
+ defaultMessage: 'click to send an email to {user}',
+ });
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/__mocks__/mock.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/__mocks__/mock.ts
index 6d76fde49634..5e0293325289 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/__mocks__/mock.ts
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/__mocks__/mock.ts
@@ -71,7 +71,7 @@ export const mockRule = (id: string): Rule => ({
to: 'now',
type: 'saved_query',
threat: [],
- throttle: null,
+ throttle: 'no_actions',
note: '# this is some markdown documentation',
version: 1,
});
@@ -145,7 +145,7 @@ export const mockRuleWithEverything = (id: string): Rule => ({
],
},
],
- throttle: null,
+ throttle: 'no_actions',
note: '# this is some markdown documentation',
version: 1,
});
@@ -184,7 +184,7 @@ export const mockActionsStepRule = (isNew = false, enabled = false): ActionsStep
actions: [],
kibanaSiemAppUrl: 'http://localhost:5601/app/siem',
enabled,
- throttle: null,
+ throttle: 'no_actions',
});
export const mockDefineStepRule = (isNew = false): DefineStepRule => ({
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx
index ebdf0fc27b6c..a155f3eb2803 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx
@@ -48,7 +48,6 @@ export const getActions = (
icon: 'controlsHorizontal',
name: i18n.EDIT_RULE_SETTINGS,
onClick: (rowItem: Rule) => editRuleAction(rowItem, history),
- enabled: (rowItem: Rule) => !rowItem.immutable,
},
{
description: i18n.DUPLICATE_RULE,
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_rule_actions/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_rule_actions/index.tsx
index 9c16a6182266..aec315938b6a 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_rule_actions/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_rule_actions/index.tsx
@@ -141,6 +141,7 @@ const StepRuleActionsComponent: FC = ({
/>
>
)}
+
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_rule_actions/schema.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_rule_actions/schema.tsx
index 511427978db3..bc3b0dfe720b 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_rule_actions/schema.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_rule_actions/schema.tsx
@@ -10,6 +10,7 @@ import { FormSchema } from '../../../../../shared_imports';
export const schema: FormSchema = {
actions: {},
+ enabled: {},
kibanaSiemAppUrl: {},
throttle: {
label: i18n.translate(
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/create/helpers.test.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/create/helpers.test.ts
index 212147ec6d4d..efb601b6bd20 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/create/helpers.test.ts
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/create/helpers.test.ts
@@ -515,10 +515,9 @@ describe('helpers', () => {
actions: [],
enabled: false,
meta: {
- throttle: 'no_actions',
kibanaSiemAppUrl: 'http://localhost:5601/app/siem',
},
- throttle: null,
+ throttle: 'no_actions',
};
expect(result).toEqual(expected);
@@ -534,10 +533,9 @@ describe('helpers', () => {
actions: [],
enabled: false,
meta: {
- throttle: mockStepData.throttle,
kibanaSiemAppUrl: mockStepData.kibanaSiemAppUrl,
},
- throttle: null,
+ throttle: 'no_actions',
};
expect(result).toEqual(expected);
@@ -568,10 +566,9 @@ describe('helpers', () => {
],
enabled: false,
meta: {
- throttle: mockStepData.throttle,
kibanaSiemAppUrl: mockStepData.kibanaSiemAppUrl,
},
- throttle: null,
+ throttle: 'rule',
};
expect(result).toEqual(expected);
@@ -602,7 +599,6 @@ describe('helpers', () => {
],
enabled: false,
meta: {
- throttle: mockStepData.throttle,
kibanaSiemAppUrl: mockStepData.kibanaSiemAppUrl,
},
throttle: mockStepData.throttle,
@@ -635,10 +631,9 @@ describe('helpers', () => {
],
enabled: false,
meta: {
- throttle: null,
kibanaSiemAppUrl: mockStepData.kibanaSiemAppUrl,
},
- throttle: null,
+ throttle: 'no_actions',
};
expect(result).toEqual(expected);
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/create/helpers.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/create/helpers.ts
index 1bc5d85258ff..151e3a9bdf4d 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/create/helpers.ts
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/create/helpers.ts
@@ -8,10 +8,7 @@ import { has, isEmpty } from 'lodash/fp';
import moment from 'moment';
import deepmerge from 'deepmerge';
-import {
- NOTIFICATION_THROTTLE_RULE,
- NOTIFICATION_THROTTLE_NO_ACTIONS,
-} from '../../../../../common/constants';
+import { NOTIFICATION_THROTTLE_NO_ACTIONS } from '../../../../../common/constants';
import { transformAlertToRuleAction } from '../../../../../common/detection_engine/transform_actions';
import { RuleType } from '../../../../../common/detection_engine/types';
import { isMlRule } from '../../../../../common/detection_engine/ml_helpers';
@@ -145,11 +142,6 @@ export const formatAboutStepData = (aboutStepData: AboutStepRule): AboutStepRule
};
};
-export const getAlertThrottle = (throttle: string | null) =>
- throttle && ![NOTIFICATION_THROTTLE_NO_ACTIONS, NOTIFICATION_THROTTLE_RULE].includes(throttle)
- ? throttle
- : null;
-
export const formatActionsStepData = (actionsStepData: ActionsStepRule): ActionsStepRuleJson => {
const {
actions = [],
@@ -161,9 +153,8 @@ export const formatActionsStepData = (actionsStepData: ActionsStepRule): Actions
return {
actions: actions.map(transformAlertToRuleAction),
enabled,
- throttle: actions.length ? getAlertThrottle(throttle) : null,
+ throttle: actions.length ? throttle : NOTIFICATION_THROTTLE_NO_ACTIONS,
meta: {
- throttle: actions.length ? throttle : NOTIFICATION_THROTTLE_NO_ACTIONS,
kibanaSiemAppUrl,
},
};
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/index.tsx
index a35caf4acf67..b8e2310ef061 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/index.tsx
@@ -277,7 +277,7 @@ const RuleDetailsPageComponent: FC = ({
{ruleI18n.EDIT_RULE_SETTINGS}
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/edit/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/edit/index.tsx
index f89e3206cc67..60d6158987a1 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/edit/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/edit/index.tsx
@@ -119,6 +119,7 @@ const EditRulePageComponent: FC = () => {
{
id: RuleStep.defineRule,
name: ruleI18n.DEFINITION,
+ disabled: rule?.immutable,
content: (
<>
@@ -140,6 +141,7 @@ const EditRulePageComponent: FC = () => {
{
id: RuleStep.aboutRule,
name: ruleI18n.ABOUT,
+ disabled: rule?.immutable,
content: (
<>
@@ -161,6 +163,7 @@ const EditRulePageComponent: FC = () => {
{
id: RuleStep.scheduleRule,
name: ruleI18n.SCHEDULE,
+ disabled: rule?.immutable,
content: (
<>
@@ -203,6 +206,7 @@ const EditRulePageComponent: FC = () => {
},
],
[
+ rule,
loading,
initLoading,
isLoading,
@@ -331,10 +335,11 @@ const EditRulePageComponent: FC = () => {
}, [rule]);
useEffect(() => {
- setSelectedTab(tabs[0]);
- }, []);
+ const tabIndex = rule?.immutable ? 3 : 0;
+ setSelectedTab(tabs[tabIndex]);
+ }, [rule]);
- if (isSaved || (rule != null && rule.immutable)) {
+ if (isSaved) {
displaySuccessToast(i18n.SUCCESSFULLY_SAVED_RULE(rule?.name ?? ''), dispatchToaster);
return ;
}
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/helpers.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/helpers.test.tsx
index fbdfcf4fc75d..522464d585cc 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/helpers.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/helpers.test.tsx
@@ -107,7 +107,12 @@ describe('rule helpers', () => {
],
};
const scheduleRuleStepData = { from: '0s', interval: '5m', isNew: false };
- const ruleActionsStepData = { enabled: true, throttle: undefined, isNew: false, actions: [] };
+ const ruleActionsStepData = {
+ enabled: true,
+ throttle: 'no_actions',
+ isNew: false,
+ actions: [],
+ };
const aboutRuleDataDetailsData = {
note: '# this is some markdown documentation',
description: '24/7',
@@ -303,7 +308,7 @@ describe('rule helpers', () => {
actions: [],
enabled: mockedRule.enabled,
isNew: false,
- throttle: undefined,
+ throttle: 'no_actions',
};
expect(result).toEqual(expected);
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/helpers.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/helpers.tsx
index 710dd2cabeb6..b6afba527ccd 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/helpers.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/helpers.tsx
@@ -58,12 +58,12 @@ export const getStepsData = ({
export const getActionsStepsData = (
rule: Omit & { actions: RuleAlertAction[] }
): ActionsStepRule => {
- const { enabled, actions = [], meta } = rule;
+ const { enabled, throttle, meta, actions = [] } = rule;
return {
actions: actions?.map(transformRuleToAlertAction),
isNew: false,
- throttle: meta?.throttle,
+ throttle,
kibanaSiemAppUrl: meta?.kibanaSiemAppUrl,
enabled,
};
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/types.ts
index edcd821353bc..128a7965cd7d 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/types.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/types.ts
@@ -49,7 +49,7 @@ export type UpdateNotificationParams = Omit {
router.post(
@@ -40,6 +41,7 @@ export const createRulesBulkRoute = (router: IRouter) => {
const alertsClient = context.alerting?.getAlertsClient();
const actionsClient = context.actions?.getActionsClient();
const clusterClient = context.core.elasticsearch.dataClient;
+ const savedObjectsClient = context.core.savedObjects.client;
const siemClient = context.siem?.getSiemClient();
if (!siemClient || !actionsClient || !alertsClient) {
@@ -112,7 +114,6 @@ export const createRulesBulkRoute = (router: IRouter) => {
const createdRule = await createRules({
alertsClient,
actionsClient,
- actions,
anomalyThreshold,
description,
enabled,
@@ -136,7 +137,6 @@ export const createRulesBulkRoute = (router: IRouter) => {
name,
severity,
tags,
- throttle,
to,
type,
threat,
@@ -145,7 +145,18 @@ export const createRulesBulkRoute = (router: IRouter) => {
version,
lists,
});
- return transformValidateBulkError(ruleIdOrUuid, createdRule);
+
+ const ruleActions = await updateRulesNotifications({
+ ruleAlertId: createdRule.id,
+ alertsClient,
+ savedObjectsClient,
+ enabled,
+ actions,
+ throttle,
+ name,
+ });
+
+ return transformValidateBulkError(ruleIdOrUuid, createdRule, ruleActions);
} catch (err) {
return transformBulkError(ruleIdOrUuid, err);
}
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.test.ts
index a77911bbb35e..f15f47432f83 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.test.ts
@@ -15,13 +15,12 @@ import {
getEmptyIndex,
getFindResultWithSingleHit,
createMlRuleRequest,
- createRuleWithActionsRequest,
} from '../__mocks__/request_responses';
import { requestContextMock, serverMock, requestMock } from '../__mocks__';
import { createRulesRoute } from './create_rules_route';
import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../feature_flags';
-import { createNotifications } from '../../notifications/create_notifications';
-jest.mock('../../notifications/create_notifications');
+import { updateRulesNotifications } from '../../rules/update_rules_notifications';
+jest.mock('../../rules/update_rules_notifications');
describe('create_rules', () => {
let server: ReturnType;
@@ -49,6 +48,12 @@ describe('create_rules', () => {
describe('status codes with actionClient and alertClient', () => {
test('returns 200 when creating a single rule with a valid actionClient and alertClient', async () => {
+ (updateRulesNotifications as jest.Mock).mockResolvedValue({
+ id: 'id',
+ actions: [],
+ alertThrottle: null,
+ ruleThrottle: 'no_actions',
+ });
const response = await server.inject(getCreateRequest(), context);
expect(response.status).toEqual(200);
});
@@ -93,18 +98,6 @@ describe('create_rules', () => {
});
});
- describe('creating a Notification if throttle and actions were provided ', () => {
- it('is successful', async () => {
- const response = await server.inject(createRuleWithActionsRequest(), context);
- expect(response.status).toEqual(200);
- expect(createNotifications).toHaveBeenCalledWith(
- expect.objectContaining({
- ruleAlertId: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
- })
- );
- });
- });
-
describe('unhappy paths', () => {
test('it returns a 400 if the index does not exist', async () => {
clients.clusterClient.callAsCurrentUser.mockResolvedValue(getEmptyIndex());
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.ts
index f68f204c1273..6038ad209532 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.ts
@@ -22,7 +22,7 @@ import {
buildSiemResponse,
validateLicenseForRuleType,
} from '../utils';
-import { createNotifications } from '../../notifications/create_notifications';
+import { updateRulesNotifications } from '../../rules/update_rules_notifications';
export const createRulesRoute = (router: IRouter): void => {
router.post(
@@ -102,7 +102,6 @@ export const createRulesRoute = (router: IRouter): void => {
const createdRule = await createRules({
alertsClient,
actionsClient,
- actions,
anomalyThreshold,
description,
enabled,
@@ -126,7 +125,6 @@ export const createRulesRoute = (router: IRouter): void => {
name,
severity,
tags,
- throttle,
to,
type,
threat,
@@ -136,16 +134,15 @@ export const createRulesRoute = (router: IRouter): void => {
lists,
});
- if (throttle && actions.length) {
- await createNotifications({
- alertsClient,
- enabled,
- name,
- interval,
- actions,
- ruleAlertId: createdRule.id,
- });
- }
+ const ruleActions = await updateRulesNotifications({
+ ruleAlertId: createdRule.id,
+ alertsClient,
+ savedObjectsClient,
+ enabled,
+ actions,
+ throttle,
+ name,
+ });
const ruleStatuses = await savedObjectsClient.find<
IRuleSavedAttributesSavedObjectAttributes
@@ -157,7 +154,11 @@ export const createRulesRoute = (router: IRouter): void => {
search: `${createdRule.id}`,
searchFields: ['alertId'],
});
- const [validated, errors] = transformValidate(createdRule, ruleStatuses.saved_objects[0]);
+ const [validated, errors] = transformValidate(
+ createdRule,
+ ruleActions,
+ ruleStatuses.saved_objects[0]
+ );
if (errors != null) {
return siemResponse.error({ statusCode: 500, body: errors });
} else {
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts
index 33ffc245e766..0c5ad2e06092 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts
@@ -18,6 +18,7 @@ import {
import { deleteRules } from '../../rules/delete_rules';
import { deleteNotifications } from '../../notifications/delete_notifications';
import { ruleStatusSavedObjectType } from '../../rules/saved_object_mappings';
+import { deleteRuleActionsSavedObject } from '../../rule_actions/delete_rule_actions_saved_object';
type Config = RouteConfig;
type Handler = RequestHandler;
@@ -56,6 +57,10 @@ export const deleteRulesBulkRoute = (router: IRouter) => {
});
if (rule != null) {
await deleteNotifications({ alertsClient, ruleAlertId: rule.id });
+ await deleteRuleActionsSavedObject({
+ ruleAlertId: rule.id,
+ savedObjectsClient,
+ });
const ruleStatuses = await savedObjectsClient.find<
IRuleSavedAttributesSavedObjectAttributes
>({
@@ -67,7 +72,7 @@ export const deleteRulesBulkRoute = (router: IRouter) => {
ruleStatuses.saved_objects.forEach(async obj =>
savedObjectsClient.delete(ruleStatusSavedObjectType, obj.id)
);
- return transformValidateBulkError(idOrRuleIdOrUnknown, rule, ruleStatuses);
+ return transformValidateBulkError(idOrRuleIdOrUnknown, rule, undefined, ruleStatuses);
} else {
return getIdBulkError({ id, ruleId });
}
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_route.ts
index a4e659da76bb..71724e3ba9b5 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_route.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_route.ts
@@ -17,6 +17,7 @@ import {
} from '../../rules/types';
import { ruleStatusSavedObjectType } from '../../rules/saved_object_mappings';
import { deleteNotifications } from '../../notifications/delete_notifications';
+import { deleteRuleActionsSavedObject } from '../../rule_actions/delete_rule_actions_saved_object';
export const deleteRulesRoute = (router: IRouter) => {
router.delete(
@@ -51,6 +52,10 @@ export const deleteRulesRoute = (router: IRouter) => {
});
if (rule != null) {
await deleteNotifications({ alertsClient, ruleAlertId: rule.id });
+ await deleteRuleActionsSavedObject({
+ ruleAlertId: rule.id,
+ savedObjectsClient,
+ });
const ruleStatuses = await savedObjectsClient.find<
IRuleSavedAttributesSavedObjectAttributes
>({
@@ -62,7 +67,11 @@ export const deleteRulesRoute = (router: IRouter) => {
ruleStatuses.saved_objects.forEach(async obj =>
savedObjectsClient.delete(ruleStatusSavedObjectType, obj.id)
);
- const [validated, errors] = transformValidate(rule, ruleStatuses.saved_objects[0]);
+ const [validated, errors] = transformValidate(
+ rule,
+ undefined,
+ ruleStatuses.saved_objects[0]
+ );
if (errors != null) {
return siemResponse.error({ statusCode: 500, body: errors });
} else {
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_route.ts
index 77351d2e0751..85555c1a5708 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_route.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_route.ts
@@ -15,6 +15,7 @@ import { findRulesSchema } from '../schemas/find_rules_schema';
import { transformValidateFindAlerts } from './validate';
import { buildRouteValidation, transformError, buildSiemResponse } from '../utils';
import { ruleStatusSavedObjectType } from '../../rules/saved_object_mappings';
+import { getRuleActionsSavedObject } from '../../rule_actions/get_rule_actions_saved_object';
export const findRulesRoute = (router: IRouter) => {
router.get(
@@ -62,7 +63,18 @@ export const findRulesRoute = (router: IRouter) => {
return results;
})
);
- const [validated, errors] = transformValidateFindAlerts(rules, ruleStatuses);
+ const ruleActions = await Promise.all(
+ rules.data.map(async rule => {
+ const results = await getRuleActionsSavedObject({
+ savedObjectsClient,
+ ruleAlertId: rule.id,
+ });
+
+ return results;
+ })
+ );
+
+ const [validated, errors] = transformValidateFindAlerts(rules, ruleActions, ruleStatuses);
if (errors != null) {
return siemResponse.error({ statusCode: 500, body: errors });
} else {
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.ts
index d9fc89740c9e..43e970702ba7 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.ts
@@ -109,7 +109,6 @@ export const importRulesRoute = (router: IRouter, config: LegacyServices['config
return null;
}
const {
- actions,
anomaly_threshold: anomalyThreshold,
description,
enabled,
@@ -132,7 +131,6 @@ export const importRulesRoute = (router: IRouter, config: LegacyServices['config
severity,
tags,
threat,
- throttle,
to,
type,
references,
@@ -168,7 +166,6 @@ export const importRulesRoute = (router: IRouter, config: LegacyServices['config
await createRules({
alertsClient,
actionsClient,
- actions,
anomalyThreshold,
description,
enabled,
@@ -195,7 +192,6 @@ export const importRulesRoute = (router: IRouter, config: LegacyServices['config
to,
type,
threat,
- throttle,
references,
note,
version,
@@ -206,7 +202,6 @@ export const importRulesRoute = (router: IRouter, config: LegacyServices['config
await patchRules({
alertsClient,
actionsClient,
- actions,
savedObjectsClient,
description,
enabled,
@@ -233,7 +228,6 @@ export const importRulesRoute = (router: IRouter, config: LegacyServices['config
to,
type,
threat,
- throttle,
references,
note,
version,
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.ts
index b19039321a6d..85255594ee48 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.ts
@@ -22,6 +22,7 @@ import { patchRulesBulkSchema } from '../schemas/patch_rules_bulk_schema';
import { rulesBulkSchema } from '../schemas/response/rules_bulk_schema';
import { patchRules } from '../../rules/patch_rules';
import { ruleStatusSavedObjectType } from '../../rules/saved_object_mappings';
+import { updateRulesNotifications } from '../../rules/update_rules_notifications';
export const patchRulesBulkRoute = (router: IRouter) => {
router.patch(
@@ -89,7 +90,6 @@ export const patchRulesBulkRoute = (router: IRouter) => {
const rule = await patchRules({
alertsClient,
actionsClient,
- actions,
description,
enabled,
falsePositives,
@@ -115,7 +115,6 @@ export const patchRulesBulkRoute = (router: IRouter) => {
to,
type,
threat,
- throttle,
references,
note,
version,
@@ -123,6 +122,15 @@ export const patchRulesBulkRoute = (router: IRouter) => {
machineLearningJobId,
});
if (rule != null) {
+ const ruleActions = await updateRulesNotifications({
+ ruleAlertId: rule.id,
+ alertsClient,
+ savedObjectsClient,
+ enabled: rule.enabled!,
+ actions,
+ throttle,
+ name: rule.name!,
+ });
const ruleStatuses = await savedObjectsClient.find<
IRuleSavedAttributesSavedObjectAttributes
>({
@@ -133,7 +141,12 @@ export const patchRulesBulkRoute = (router: IRouter) => {
search: rule.id,
searchFields: ['alertId'],
});
- return transformValidateBulkError(rule.id, rule, ruleStatuses.saved_objects[0]);
+ return transformValidateBulkError(
+ rule.id,
+ rule,
+ ruleActions,
+ ruleStatuses.saved_objects[0]
+ );
} else {
return getIdBulkError({ id, ruleId });
}
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts
index 1e344d8ea7e3..dbb0a3bb3e1d 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts
@@ -35,6 +35,7 @@ describe('patch_rules', () => {
server = serverMock.create();
({ clients, context } = requestContextMock.createTools());
+ clients.alertsClient.get.mockResolvedValue(getResult()); // existing rule
clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); // existing rule
clients.alertsClient.update.mockResolvedValue(getResult()); // successful update
clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); // successful transform
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_route.ts
index fab53079361a..f553ccd2c6f8 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_route.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_route.ts
@@ -21,6 +21,7 @@ import {
import { getIdError } from './utils';
import { transformValidate } from './validate';
import { ruleStatusSavedObjectType } from '../../rules/saved_object_mappings';
+import { updateRulesNotifications } from '../../rules/update_rules_notifications';
export const patchRulesRoute = (router: IRouter) => {
router.patch(
@@ -85,7 +86,6 @@ export const patchRulesRoute = (router: IRouter) => {
const rule = await patchRules({
actionsClient,
alertsClient,
- actions,
description,
enabled,
falsePositives,
@@ -111,7 +111,6 @@ export const patchRulesRoute = (router: IRouter) => {
to,
type,
threat,
- throttle,
references,
note,
version,
@@ -119,6 +118,15 @@ export const patchRulesRoute = (router: IRouter) => {
machineLearningJobId,
});
if (rule != null) {
+ const ruleActions = await updateRulesNotifications({
+ ruleAlertId: rule.id,
+ alertsClient,
+ savedObjectsClient,
+ enabled: rule.enabled!,
+ actions,
+ throttle,
+ name: rule.name!,
+ });
const ruleStatuses = await savedObjectsClient.find<
IRuleSavedAttributesSavedObjectAttributes
>({
@@ -130,7 +138,11 @@ export const patchRulesRoute = (router: IRouter) => {
searchFields: ['alertId'],
});
- const [validated, errors] = transformValidate(rule, ruleStatuses.saved_objects[0]);
+ const [validated, errors] = transformValidate(
+ rule,
+ ruleActions,
+ ruleStatuses.saved_objects[0]
+ );
if (errors != null) {
return siemResponse.error({ statusCode: 500, body: errors });
} else {
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/read_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/read_rules_route.ts
index bc52445feee7..77747448e94f 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/read_rules_route.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/read_rules_route.ts
@@ -16,6 +16,7 @@ import {
IRuleSavedAttributesSavedObjectAttributes,
} from '../../rules/types';
import { ruleStatusSavedObjectType } from '../../rules/saved_object_mappings';
+import { getRuleActionsSavedObject } from '../../rule_actions/get_rule_actions_saved_object';
export const readRulesRoute = (router: IRouter) => {
router.get(
@@ -46,6 +47,10 @@ export const readRulesRoute = (router: IRouter) => {
ruleId,
});
if (rule != null) {
+ const ruleActions = await getRuleActionsSavedObject({
+ savedObjectsClient,
+ ruleAlertId: rule.id,
+ });
const ruleStatuses = await savedObjectsClient.find<
IRuleSavedAttributesSavedObjectAttributes
>({
@@ -56,7 +61,11 @@ export const readRulesRoute = (router: IRouter) => {
search: rule.id,
searchFields: ['alertId'],
});
- const [validated, errors] = transformValidate(rule, ruleStatuses.saved_objects[0]);
+ const [validated, errors] = transformValidate(
+ rule,
+ ruleActions,
+ ruleStatuses.saved_objects[0]
+ );
if (errors != null) {
return siemResponse.error({ statusCode: 500, body: errors });
} else {
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts
index 789f7d1ca074..9916972f4184 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts
@@ -22,6 +22,7 @@ import { updateRulesBulkSchema } from '../schemas/update_rules_bulk_schema';
import { ruleStatusSavedObjectType } from '../../rules/saved_object_mappings';
import { updateRules } from '../../rules/update_rules';
import { rulesBulkSchema } from '../schemas/response/rules_bulk_schema';
+import { updateRulesNotifications } from '../../rules/update_rules_notifications';
export const updateRulesBulkRoute = (router: IRouter) => {
router.put(
@@ -90,11 +91,9 @@ export const updateRulesBulkRoute = (router: IRouter) => {
const rule = await updateRules({
alertsClient,
actionsClient,
- actions,
anomalyThreshold,
description,
enabled,
- immutable: false,
falsePositives,
from,
query,
@@ -119,13 +118,21 @@ export const updateRulesBulkRoute = (router: IRouter) => {
to,
type,
threat,
- throttle,
references,
note,
version,
lists,
});
if (rule != null) {
+ const ruleActions = await updateRulesNotifications({
+ ruleAlertId: rule.id,
+ alertsClient,
+ savedObjectsClient,
+ enabled,
+ actions,
+ throttle,
+ name,
+ });
const ruleStatuses = await savedObjectsClient.find<
IRuleSavedAttributesSavedObjectAttributes
>({
@@ -136,7 +143,12 @@ export const updateRulesBulkRoute = (router: IRouter) => {
search: rule.id,
searchFields: ['alertId'],
});
- return transformValidateBulkError(rule.id, rule, ruleStatuses.saved_objects[0]);
+ return transformValidateBulkError(
+ rule.id,
+ rule,
+ ruleActions,
+ ruleStatuses.saved_objects[0]
+ );
} else {
return getIdBulkError({ id, ruleId });
}
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.test.ts
index 454fe1f0706c..53c52153e84e 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.test.ts
@@ -18,6 +18,8 @@ import {
import { requestContextMock, serverMock, requestMock } from '../__mocks__';
import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../feature_flags';
+import { updateRulesNotifications } from '../../rules/update_rules_notifications';
+jest.mock('../../rules/update_rules_notifications');
describe('update_rules', () => {
let server: ReturnType;
@@ -35,6 +37,7 @@ describe('update_rules', () => {
server = serverMock.create();
({ clients, context } = requestContextMock.createTools());
+ clients.alertsClient.get.mockResolvedValue(getResult()); // existing rule
clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); // rule exists
clients.alertsClient.update.mockResolvedValue(getResult()); // successful update
clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatusEmpty()); // successful transform
@@ -44,6 +47,12 @@ describe('update_rules', () => {
describe('status codes with actionClient and alertClient', () => {
test('returns 200 when updating a single rule with a valid actionClient and alertClient', async () => {
+ (updateRulesNotifications as jest.Mock).mockResolvedValue({
+ id: 'id',
+ actions: [],
+ alertThrottle: null,
+ ruleThrottle: 'no_actions',
+ });
const response = await server.inject(getUpdateRequest(), context);
expect(response.status).toEqual(200);
});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.ts
index 5856575eb979..21dd2a4429cc 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.ts
@@ -21,7 +21,7 @@ import { getIdError } from './utils';
import { transformValidate } from './validate';
import { ruleStatusSavedObjectType } from '../../rules/saved_object_mappings';
import { updateRules } from '../../rules/update_rules';
-import { updateNotifications } from '../../notifications/update_notifications';
+import { updateRulesNotifications } from '../../rules/update_rules_notifications';
export const updateRulesRoute = (router: IRouter) => {
router.put(
@@ -87,13 +87,11 @@ export const updateRulesRoute = (router: IRouter) => {
const rule = await updateRules({
alertsClient,
actionsClient,
- actions,
anomalyThreshold,
description,
enabled,
falsePositives,
from,
- immutable: false,
query,
language,
machineLearningJobId,
@@ -116,7 +114,6 @@ export const updateRulesRoute = (router: IRouter) => {
to,
type,
threat,
- throttle,
references,
note,
version,
@@ -124,15 +121,15 @@ export const updateRulesRoute = (router: IRouter) => {
});
if (rule != null) {
- await updateNotifications({
+ const ruleActions = await updateRulesNotifications({
+ ruleAlertId: rule.id,
alertsClient,
- actions,
+ savedObjectsClient,
enabled,
- ruleAlertId: rule.id,
- interval: throttle,
+ actions,
+ throttle,
name,
});
-
const ruleStatuses = await savedObjectsClient.find<
IRuleSavedAttributesSavedObjectAttributes
>({
@@ -143,7 +140,11 @@ export const updateRulesRoute = (router: IRouter) => {
search: rule.id,
searchFields: ['alertId'],
});
- const [validated, errors] = transformValidate(rule, ruleStatuses.saved_objects[0]);
+ const [validated, errors] = transformValidate(
+ rule,
+ ruleActions,
+ ruleStatuses.saved_objects[0]
+ );
if (errors != null) {
return siemResponse.error({ statusCode: 500, body: errors });
} else {
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
index 3a047f91a0bc..31a0f37fe81c 100644
--- 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
@@ -215,17 +215,20 @@ describe('utils', () => {
describe('transformFindAlerts', () => {
test('outputs empty data set when data set is empty correct', () => {
- const output = transformFindAlerts({ data: [], page: 1, perPage: 0, total: 0 });
+ const output = transformFindAlerts({ data: [], page: 1, perPage: 0, total: 0 }, []);
expect(output).toEqual({ data: [], page: 1, perPage: 0, total: 0 });
});
test('outputs 200 if the data is of type siem alert', () => {
- const output = transformFindAlerts({
- page: 1,
- perPage: 0,
- total: 0,
- data: [getResult()],
- });
+ const output = transformFindAlerts(
+ {
+ page: 1,
+ perPage: 0,
+ total: 0,
+ data: [getResult()],
+ },
+ []
+ );
const expected = getOutputRuleAlertForRest();
expect(output).toEqual({
page: 1,
@@ -237,12 +240,15 @@ describe('utils', () => {
test('returns 500 if the data is not of type siem alert', () => {
const unsafeCast = ([{ name: 'something else' }] as unknown) as SanitizedAlert[];
- const output = transformFindAlerts({
- data: unsafeCast,
- page: 1,
- perPage: 1,
- total: 1,
- });
+ const output = transformFindAlerts(
+ {
+ data: unsafeCast,
+ page: 1,
+ perPage: 1,
+ total: 1,
+ },
+ []
+ );
expect(output).toBeNull();
});
});
@@ -364,14 +370,24 @@ describe('utils', () => {
describe('transformOrBulkError', () => {
test('outputs 200 if the data is of type siem alert', () => {
- const output = transformOrBulkError('rule-1', getResult());
+ const output = transformOrBulkError('rule-1', getResult(), {
+ id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
+ actions: [],
+ ruleThrottle: 'no_actions',
+ alertThrottle: null,
+ });
const expected = getOutputRuleAlertForRest();
expect(output).toEqual(expected);
});
test('returns 500 if the data is not of type siem alert', () => {
const unsafeCast = ({ name: 'something else' } as unknown) as PartialAlert;
- const output = transformOrBulkError('rule-1', unsafeCast);
+ const output = transformOrBulkError('rule-1', unsafeCast, {
+ id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
+ actions: [],
+ ruleThrottle: 'no_actions',
+ alertThrottle: null,
+ });
const expected: BulkError = {
rule_id: 'rule-1',
error: { message: 'Internal error transforming', status_code: 500 },
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
index a0458dc3a133..4d13fa1b6ae5 100644
--- 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
@@ -29,7 +29,8 @@ import {
OutputError,
} from '../utils';
import { hasListsFeature } from '../../feature_flags';
-import { transformAlertToRuleAction } from '../../../../../common/detection_engine/transform_actions';
+// import { transformAlertToRuleAction } from '../../../../../common/detection_engine/transform_actions';
+import { RuleActions } from '../../rule_actions/types';
type PromiseFromStreams = ImportRuleAlertRest | Error;
@@ -100,10 +101,11 @@ export const transformTags = (tags: string[]): string[] => {
// those on the export
export const transformAlertToRule = (
alert: RuleAlertType,
+ ruleActions?: RuleActions | null,
ruleStatus?: SavedObject
): Partial => {
return pickBy((value: unknown) => value != null, {
- actions: alert.actions.map(transformAlertToRuleAction),
+ actions: ruleActions?.actions ?? [],
created_at: alert.createdAt.toISOString(),
updated_at: alert.updatedAt.toISOString(),
created_by: alert.createdBy,
@@ -136,7 +138,7 @@ export const transformAlertToRule = (
to: alert.params.to,
type: alert.params.type,
threat: alert.params.threat,
- throttle: alert.throttle,
+ throttle: ruleActions?.ruleThrottle || 'no_actions',
note: alert.params.note,
version: alert.params.version,
status: ruleStatus?.attributes.status,
@@ -167,6 +169,7 @@ export const transformAlertsToRules = (
export const transformFindAlerts = (
findResults: FindResult,
+ ruleActions: Array,
ruleStatuses?: Array>
): {
page: number;
@@ -179,7 +182,7 @@ export const transformFindAlerts = (
page: findResults.page,
perPage: findResults.perPage,
total: findResults.total,
- data: findResults.data.map(alert => transformAlertToRule(alert)),
+ data: findResults.data.map((alert, idx) => transformAlertToRule(alert, ruleActions[idx])),
};
} else if (isAlertTypes(findResults.data) && isRuleStatusFindTypes(ruleStatuses)) {
return {
@@ -187,7 +190,7 @@ export const transformFindAlerts = (
perPage: findResults.perPage,
total: findResults.total,
data: findResults.data.map((alert, idx) =>
- transformAlertToRule(alert, ruleStatuses[idx].saved_objects[0])
+ transformAlertToRule(alert, ruleActions[idx], ruleStatuses[idx].saved_objects[0])
),
};
} else {
@@ -197,28 +200,31 @@ export const transformFindAlerts = (
export const transform = (
alert: PartialAlert,
+ ruleActions?: RuleActions | null,
ruleStatus?: SavedObject
): Partial | null => {
- if (!ruleStatus && isAlertType(alert)) {
- return transformAlertToRule(alert);
- }
- if (isAlertType(alert) && isRuleStatusSavedObjectType(ruleStatus)) {
- return transformAlertToRule(alert, ruleStatus);
- } else {
- return null;
+ if (isAlertType(alert)) {
+ return transformAlertToRule(
+ alert,
+ ruleActions,
+ isRuleStatusSavedObjectType(ruleStatus) ? ruleStatus : undefined
+ );
}
+
+ return null;
};
export const transformOrBulkError = (
ruleId: string,
alert: PartialAlert,
+ ruleActions: RuleActions,
ruleStatus?: unknown
): Partial | BulkError => {
if (isAlertType(alert)) {
if (isRuleStatusFindType(ruleStatus) && ruleStatus?.saved_objects.length > 0) {
- return transformAlertToRule(alert, ruleStatus?.saved_objects[0] ?? ruleStatus);
+ return transformAlertToRule(alert, ruleActions, ruleStatus?.saved_objects[0] ?? ruleStatus);
} else {
- return transformAlertToRule(alert);
+ return transformAlertToRule(alert, ruleActions);
}
} else {
return createBulkErrorObject({
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/validate.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/validate.test.ts
index 3727908ac62d..77e05796fbcb 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/validate.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/validate.test.ts
@@ -43,6 +43,7 @@ export const ruleOutput: RulesSchema = {
tags: [],
to: 'now',
type: 'query',
+ throttle: 'no_actions',
threat: [
{
framework: 'MITRE ATT&CK',
@@ -154,7 +155,7 @@ describe('validate', () => {
describe('transformValidateFindAlerts', () => {
test('it should do a validation correctly of a find alert', () => {
const findResult: FindResult = { data: [getResult()], page: 1, perPage: 0, total: 0 };
- const [validated, errors] = transformValidateFindAlerts(findResult);
+ const [validated, errors] = transformValidateFindAlerts(findResult, []);
expect(validated).toEqual({ data: [ruleOutput], page: 1, perPage: 0, total: 0 });
expect(errors).toEqual(null);
});
@@ -162,7 +163,7 @@ describe('validate', () => {
test('it should do an in-validation correctly of a partial alert', () => {
const findResult: FindResult = { data: [getResult()], page: 1, perPage: 0, total: 0 };
delete findResult.page;
- const [validated, errors] = transformValidateFindAlerts(findResult);
+ const [validated, errors] = transformValidateFindAlerts(findResult, []);
expect(validated).toEqual(null);
expect(errors).toEqual('Invalid value "undefined" supplied to "page"');
});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/validate.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/validate.ts
index e654da99fe67..1f3d1ec85668 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/validate.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/validate.ts
@@ -22,9 +22,11 @@ import { rulesSchema, RulesSchema } from '../schemas/response/rules_schema';
import { exactCheck } from '../schemas/response/exact_check';
import { transformFindAlerts, transform, transformAlertToRule } from './utils';
import { findRulesSchema } from '../schemas/response/find_rules_schema';
+import { RuleActions } from '../../rule_actions/types';
export const transformValidateFindAlerts = (
findResults: FindResult,
+ ruleActions: Array,
ruleStatuses?: Array>
): [
{
@@ -35,7 +37,7 @@ export const transformValidateFindAlerts = (
} | null,
string | null
] => {
- const transformed = transformFindAlerts(findResults, ruleStatuses);
+ const transformed = transformFindAlerts(findResults, ruleActions, ruleStatuses);
if (transformed == null) {
return [null, 'Internal error transforming'];
} else {
@@ -54,9 +56,10 @@ export const transformValidateFindAlerts = (
export const transformValidate = (
alert: PartialAlert,
+ ruleActions?: RuleActions | null,
ruleStatus?: SavedObject
): [RulesSchema | null, string | null] => {
- const transformed = transform(alert, ruleStatus);
+ const transformed = transform(alert, ruleActions, ruleStatus);
if (transformed == null) {
return [null, 'Internal error transforming'];
} else {
@@ -67,11 +70,16 @@ export const transformValidate = (
export const transformValidateBulkError = (
ruleId: string,
alert: PartialAlert,
+ ruleActions?: RuleActions | null,
ruleStatus?: unknown
): RulesSchema | BulkError => {
if (isAlertType(alert)) {
if (isRuleStatusFindType(ruleStatus) && ruleStatus?.saved_objects.length > 0) {
- const transformed = transformAlertToRule(alert, ruleStatus?.saved_objects[0] ?? ruleStatus);
+ const transformed = transformAlertToRule(
+ alert,
+ ruleActions,
+ ruleStatus?.saved_objects[0] ?? ruleStatus
+ );
const [validated, errors] = validate(transformed, rulesSchema);
if (errors != null || validated == null) {
return createBulkErrorObject({
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/add_prepackaged_rules_schema.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/add_prepackaged_rules_schema.ts
index da9f9777a01a..006fc81e3ee8 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/add_prepackaged_rules_schema.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/add_prepackaged_rules_schema.ts
@@ -52,7 +52,7 @@ import { hasListsFeature } from '../../feature_flags';
* - immutable is forbidden but defaults to true instead of to false and it can only ever be true
* - enabled defaults to false instead of true
* - version is a required field that must exist
- * - index is a required field that must exist
+ * - index is a required field that must exist if type !== machine_learning
*/
export const addPrepackagedRulesSchema = Joi.object({
actions: actions.default([]),
@@ -71,7 +71,11 @@ export const addPrepackagedRulesSchema = Joi.object({
.forbidden()
.default(true)
.valid(true),
- index: index.required(),
+ index: index.when('type', {
+ is: 'machine_learning',
+ then: Joi.forbidden(),
+ otherwise: Joi.required(),
+ }),
interval: interval.default('5m'),
query: query.when('type', {
is: 'machine_learning',
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/create_rule_actions_saved_object.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/create_rule_actions_saved_object.ts
new file mode 100644
index 000000000000..23c99b36cb4a
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/create_rule_actions_saved_object.ts
@@ -0,0 +1,35 @@
+/*
+ * 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 { RuleAlertAction } from '../../../../common/detection_engine/types';
+import { AlertServices } from '../../../../../../../plugins/alerting/server';
+import { ruleActionsSavedObjectType } from './saved_object_mappings';
+import { IRuleActionsAttributesSavedObjectAttributes } from './types';
+import { getThrottleOptions, getRuleActionsFromSavedObject } from './utils';
+
+interface CreateRuleActionsSavedObject {
+ ruleAlertId: string;
+ savedObjectsClient: AlertServices['savedObjectsClient'];
+ actions: RuleAlertAction[] | undefined;
+ throttle: string | undefined;
+}
+
+export const createRuleActionsSavedObject = async ({
+ ruleAlertId,
+ savedObjectsClient,
+ actions = [],
+ throttle,
+}: CreateRuleActionsSavedObject) => {
+ const ruleActionsSavedObject = await savedObjectsClient.create<
+ IRuleActionsAttributesSavedObjectAttributes
+ >(ruleActionsSavedObjectType, {
+ ruleAlertId,
+ actions,
+ ...getThrottleOptions(throttle),
+ });
+
+ return getRuleActionsFromSavedObject(ruleActionsSavedObject);
+};
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/delete_rule_actions_saved_object.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/delete_rule_actions_saved_object.ts
new file mode 100644
index 000000000000..4e8781dd4569
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/delete_rule_actions_saved_object.ts
@@ -0,0 +1,25 @@
+/*
+ * 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 { AlertServices } from '../../../../../../../plugins/alerting/server';
+import { ruleActionsSavedObjectType } from './saved_object_mappings';
+import { getRuleActionsSavedObject } from './get_rule_actions_saved_object';
+
+interface DeleteRuleActionsSavedObject {
+ ruleAlertId: string;
+ savedObjectsClient: AlertServices['savedObjectsClient'];
+}
+
+export const deleteRuleActionsSavedObject = async ({
+ ruleAlertId,
+ savedObjectsClient,
+}: DeleteRuleActionsSavedObject) => {
+ const ruleActions = await getRuleActionsSavedObject({ ruleAlertId, savedObjectsClient });
+
+ if (!ruleActions) return null;
+
+ return savedObjectsClient.delete(ruleActionsSavedObjectType, ruleActions.id);
+};
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/get_rule_actions_saved_object.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/get_rule_actions_saved_object.ts
new file mode 100644
index 000000000000..3ae9090526d6
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/get_rule_actions_saved_object.ts
@@ -0,0 +1,35 @@
+/*
+ * 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 { AlertServices } from '../../../../../../../plugins/alerting/server';
+import { ruleActionsSavedObjectType } from './saved_object_mappings';
+import { IRuleActionsAttributesSavedObjectAttributes } from './types';
+import { getRuleActionsFromSavedObject } from './utils';
+
+interface GetRuleActionsSavedObject {
+ ruleAlertId: string;
+ savedObjectsClient: AlertServices['savedObjectsClient'];
+}
+
+export const getRuleActionsSavedObject = async ({
+ ruleAlertId,
+ savedObjectsClient,
+}: GetRuleActionsSavedObject) => {
+ const { saved_objects } = await savedObjectsClient.find<
+ IRuleActionsAttributesSavedObjectAttributes
+ >({
+ type: ruleActionsSavedObjectType,
+ perPage: 1,
+ search: `${ruleAlertId}`,
+ searchFields: ['ruleAlertId'],
+ });
+
+ if (!saved_objects[0]) {
+ return null;
+ }
+
+ return getRuleActionsFromSavedObject(saved_objects[0]);
+};
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/saved_object_mappings.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/saved_object_mappings.ts
new file mode 100644
index 000000000000..f54f43c41ef6
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/saved_object_mappings.ts
@@ -0,0 +1,40 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export const ruleActionsSavedObjectType = 'siem-detection-engine-rule-actions';
+
+export const ruleActionsSavedObjectMappings = {
+ [ruleActionsSavedObjectType]: {
+ properties: {
+ alertThrottle: {
+ type: 'keyword',
+ },
+ ruleAlertId: {
+ type: 'keyword',
+ },
+ ruleThrottle: {
+ type: 'keyword',
+ },
+ actions: {
+ properties: {
+ group: {
+ type: 'keyword',
+ },
+ id: {
+ type: 'keyword',
+ },
+ action_type_id: {
+ type: 'keyword',
+ },
+ params: {
+ dynamic: true,
+ properties: {},
+ },
+ },
+ },
+ },
+ },
+};
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/types.ts
new file mode 100644
index 000000000000..525eb74d18fb
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/types.ts
@@ -0,0 +1,68 @@
+/*
+ * 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 { SavedObject, SavedObjectAttributes, SavedObjectsFindResponse } from 'kibana/server';
+import { RuleAlertAction } from '../../../../common/detection_engine/types';
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export interface IRuleActionsAttributes extends Record {
+ ruleAlertId: string;
+ actions: RuleAlertAction[];
+ ruleThrottle: string;
+ alertThrottle: string | null;
+}
+
+export interface RuleActions {
+ id: string;
+ actions: RuleAlertAction[];
+ ruleThrottle: string;
+ alertThrottle: string | null;
+}
+
+export interface IRuleActionsAttributesSavedObjectAttributes
+ extends IRuleActionsAttributes,
+ SavedObjectAttributes {}
+
+export interface RuleActionsResponse {
+ [key: string]: {
+ actions: IRuleActionsAttributes | null | undefined;
+ };
+}
+
+export interface IRuleActionsSavedObject {
+ type: string;
+ id: string;
+ attributes: Array>;
+ references: unknown[];
+ updated_at: string;
+ version: string;
+}
+
+export interface IRuleActionsFindType {
+ page: number;
+ per_page: number;
+ total: number;
+ saved_objects: IRuleActionsSavedObject[];
+}
+
+export const isRuleActionsSavedObjectType = (
+ obj: unknown
+): obj is SavedObject => {
+ return get('attributes', obj) != null;
+};
+
+export const isRuleActionsFindType = (
+ obj: unknown
+): obj is SavedObjectsFindResponse => {
+ return get('saved_objects', obj) != null;
+};
+
+export const isRuleActionsFindTypes = (
+ obj: unknown[] | undefined
+): obj is Array> => {
+ return obj ? obj.every(ruleStatus => isRuleActionsFindType(ruleStatus)) : false;
+};
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/update_or_create_rule_actions_saved_object.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/update_or_create_rule_actions_saved_object.ts
new file mode 100644
index 000000000000..3856f7525526
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/update_or_create_rule_actions_saved_object.ts
@@ -0,0 +1,39 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { AlertServices } from '../../../../../../../plugins/alerting/server';
+import { RuleAlertAction } from '../../../../common/detection_engine/types';
+import { getRuleActionsSavedObject } from './get_rule_actions_saved_object';
+import { createRuleActionsSavedObject } from './create_rule_actions_saved_object';
+import { updateRuleActionsSavedObject } from './update_rule_actions_saved_object';
+import { RuleActions } from './types';
+
+interface UpdateOrCreateRuleActionsSavedObject {
+ ruleAlertId: string;
+ savedObjectsClient: AlertServices['savedObjectsClient'];
+ actions: RuleAlertAction[] | undefined;
+ throttle: string | undefined;
+}
+
+export const updateOrCreateRuleActionsSavedObject = async ({
+ savedObjectsClient,
+ ruleAlertId,
+ actions,
+ throttle,
+}: UpdateOrCreateRuleActionsSavedObject): Promise => {
+ const currentRuleActions = await getRuleActionsSavedObject({ ruleAlertId, savedObjectsClient });
+
+ if (currentRuleActions) {
+ return updateRuleActionsSavedObject({
+ ruleAlertId,
+ savedObjectsClient,
+ actions,
+ throttle,
+ }) as Promise;
+ }
+
+ return createRuleActionsSavedObject({ ruleAlertId, savedObjectsClient, actions, throttle });
+};
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/update_rule_actions_saved_object.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/update_rule_actions_saved_object.ts
new file mode 100644
index 000000000000..56bce3c8b67a
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/update_rule_actions_saved_object.ts
@@ -0,0 +1,56 @@
+/*
+ * 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 { AlertServices } from '../../../../../../../plugins/alerting/server';
+import { ruleActionsSavedObjectType } from './saved_object_mappings';
+import { getRuleActionsSavedObject } from './get_rule_actions_saved_object';
+import { RuleAlertAction } from '../../../../common/detection_engine/types';
+import { getThrottleOptions } from './utils';
+import { IRuleActionsAttributesSavedObjectAttributes } from './types';
+
+interface DeleteRuleActionsSavedObject {
+ ruleAlertId: string;
+ savedObjectsClient: AlertServices['savedObjectsClient'];
+ actions: RuleAlertAction[] | undefined;
+ throttle: string | undefined;
+}
+
+export const updateRuleActionsSavedObject = async ({
+ ruleAlertId,
+ savedObjectsClient,
+ actions,
+ throttle,
+}: DeleteRuleActionsSavedObject) => {
+ const ruleActions = await getRuleActionsSavedObject({ ruleAlertId, savedObjectsClient });
+
+ if (!ruleActions) return null;
+
+ const throttleOptions = throttle
+ ? getThrottleOptions(throttle)
+ : {
+ ruleThrottle: ruleActions.ruleThrottle,
+ alertThrottle: ruleActions.alertThrottle,
+ };
+
+ const options = {
+ actions: actions ?? ruleActions.actions,
+ ...throttleOptions,
+ };
+
+ await savedObjectsClient.update(
+ ruleActionsSavedObjectType,
+ ruleActions.id,
+ {
+ ruleAlertId,
+ ...options,
+ }
+ );
+
+ return {
+ id: ruleActions.id,
+ ...options,
+ };
+};
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/utils.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/utils.ts
new file mode 100644
index 000000000000..3c297ed84855
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/utils.ts
@@ -0,0 +1,22 @@
+/*
+ * 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 { SavedObjectsUpdateResponse } from 'kibana/server';
+import { IRuleActionsAttributesSavedObjectAttributes } from './types';
+
+export const getThrottleOptions = (throttle = 'no_actions') => ({
+ ruleThrottle: throttle,
+ alertThrottle: ['no_actions', 'rule'].includes(throttle) ? null : throttle,
+});
+
+export const getRuleActionsFromSavedObject = (
+ savedObject: SavedObjectsUpdateResponse
+) => ({
+ id: savedObject.id,
+ actions: savedObject.attributes.actions || [],
+ alertThrottle: savedObject.attributes.alertThrottle || null,
+ ruleThrottle: savedObject.attributes.ruleThrottle || 'no_actions',
+});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.test.ts
index 14b8ffdfdace..4c8d0f51f251 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.test.ts
@@ -28,12 +28,10 @@ describe('createRules', () => {
await createRules({
alertsClient,
actionsClient,
- actions: [],
...params,
ruleId: 'new-rule-id',
enabled: true,
interval: '',
- throttle: null,
name: '',
tags: [],
});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.ts
index a45b28ba3e10..bebf4f350483 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.ts
@@ -6,15 +6,12 @@
import { Alert } from '../../../../../../../plugins/alerting/common';
import { APP_ID, SIGNALS_ID } from '../../../../common/constants';
-import { transformRuleToAlertAction } from '../../../../common/detection_engine/transform_actions';
import { CreateRuleParams } from './types';
import { addTags } from './add_tags';
import { hasListsFeature } from '../feature_flags';
export const createRules = async ({
alertsClient,
- actionsClient, // TODO: Use this actionsClient once we have actions such as email, etc...
- actions,
anomalyThreshold,
description,
enabled,
@@ -39,7 +36,6 @@ export const createRules = async ({
severity,
tags,
threat,
- throttle,
to,
type,
references,
@@ -85,8 +81,8 @@ export const createRules = async ({
},
schedule: { interval },
enabled,
- actions: actions?.map(transformRuleToAlertAction),
- throttle,
+ actions: [],
+ throttle: null,
},
});
};
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.test.ts
index 20ddcdc3f536..ca6fb15e1fad 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.test.ts
@@ -76,6 +76,7 @@ describe('getExportAll', () => {
],
},
],
+ throttle: 'no_actions',
note: '# Investigative notes',
version: 1,
lists: [
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts
index e6d4c68d7108..175c906f7996 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts
@@ -84,6 +84,7 @@ describe('get_export_by_object_ids', () => {
],
},
],
+ throttle: 'no_actions',
note: '# Investigative notes',
version: 1,
lists: [
@@ -205,6 +206,7 @@ describe('get_export_by_object_ids', () => {
],
},
],
+ throttle: 'no_actions',
note: '# Investigative notes',
version: 1,
lists: [
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/install_prepacked_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/install_prepacked_rules.ts
index 801f3d949ed7..bcbe460fb6a6 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/install_prepacked_rules.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/install_prepacked_rules.ts
@@ -18,7 +18,6 @@ export const installPrepackagedRules = (
): Array> =>
rules.reduce>>((acc, rule) => {
const {
- actions,
anomaly_threshold: anomalyThreshold,
description,
enabled,
@@ -44,7 +43,6 @@ export const installPrepackagedRules = (
to,
type,
threat,
- throttle,
references,
note,
version,
@@ -55,7 +53,6 @@ export const installPrepackagedRules = (
createRules({
alertsClient,
actionsClient,
- actions,
anomalyThreshold,
description,
enabled,
@@ -82,7 +79,6 @@ export const installPrepackagedRules = (
to,
type,
threat,
- throttle,
references,
note,
version,
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.test.ts
index cd18bee6f606..3108fc5f3b71 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.test.ts
@@ -28,12 +28,10 @@ describe('patchRules', () => {
await patchRules({
alertsClient,
actionsClient,
- actions: [],
savedObjectsClient,
id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
...rule.params,
enabled: false,
- throttle: null,
interval: '',
name: '',
tags: [],
@@ -56,12 +54,10 @@ describe('patchRules', () => {
await patchRules({
alertsClient,
actionsClient,
- actions: [],
savedObjectsClient,
id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
...rule.params,
enabled: true,
- throttle: null,
interval: '',
name: '',
tags: [],
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.ts
index 5394af526c91..d7655a15499e 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.ts
@@ -6,7 +6,6 @@
import { defaults } from 'lodash/fp';
import { PartialAlert } from '../../../../../../../plugins/alerting/server';
-import { transformRuleToAlertAction } from '../../../../common/detection_engine/transform_actions';
import { readRules } from './read_rules';
import { PatchRuleParams, IRuleSavedAttributesSavedObjectAttributes } from './types';
import { addTags } from './add_tags';
@@ -16,7 +15,6 @@ import { calculateVersion, calculateName, calculateInterval } from './utils';
export const patchRules = async ({
alertsClient,
actionsClient, // TODO: Use this whenever we add feature support for different action types
- actions,
savedObjectsClient,
description,
falsePositives,
@@ -41,7 +39,6 @@ export const patchRules = async ({
severity,
tags,
threat,
- throttle,
to,
type,
references,
@@ -57,7 +54,6 @@ export const patchRules = async ({
}
const calculatedVersion = calculateVersion(rule.params.immutable, rule.params.version, {
- actions,
description,
falsePositives,
query,
@@ -77,7 +73,6 @@ export const patchRules = async ({
severity,
tags,
threat,
- throttle,
to,
type,
references,
@@ -125,12 +120,12 @@ export const patchRules = async ({
id: rule.id,
data: {
tags: addTags(tags ?? rule.tags, rule.params.ruleId, immutable ?? rule.params.immutable),
- throttle: throttle !== undefined ? throttle : rule.throttle,
+ throttle: rule.throttle,
name: calculateName({ updatedName: name, originalName: rule.name }),
schedule: {
interval: calculateInterval(interval, rule.schedule.interval),
},
- actions: actions?.map(transformRuleToAlertAction) ?? rule.actions,
+ actions: rule.actions,
params: nextParams,
},
});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/403_response_to_a_post.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/403_response_to_a_post.json
index fd46a09d4ced..3b043439759c 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/403_response_to_a_post.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/403_response_to_a_post.json
@@ -7,7 +7,6 @@
"apm-*-transaction*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Web Application Suspicious Activity: POST Request Declined",
"query": "http.response.status_code:403 and http.request.method:post",
"references": [
@@ -17,9 +16,9 @@
"rule_id": "a87a4e42-1d82-44bd-b0bf-d9b7f91fb89e",
"severity": "medium",
"tags": [
- "Elastic",
- "APM"
+ "APM",
+ "Elastic"
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/405_response_method_not_allowed.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/405_response_method_not_allowed.json
index a6235c889902..12c6a5feabeb 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/405_response_method_not_allowed.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/405_response_method_not_allowed.json
@@ -7,7 +7,6 @@
"apm-*-transaction*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Web Application Suspicious Activity: Unauthorized Method",
"query": "http.response.status_code:405",
"references": [
@@ -17,9 +16,9 @@
"rule_id": "75ee75d8-c180-481c-ba88-ee50129a6aef",
"severity": "medium",
"tags": [
- "Elastic",
- "APM"
+ "APM",
+ "Elastic"
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_adversary_behavior_detected.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_adversary_behavior_detected.json
index 397db1367f40..a3302896b7e9 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_adversary_behavior_detected.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_adversary_behavior_detected.json
@@ -6,7 +6,6 @@
],
"interval": "10m",
"language": "kuery",
- "max_signals": 100,
"name": "Adversary Behavior - Detected - Elastic Endpoint",
"query": "event.kind:alert and event.module:endgame and event.action:rules_engine_event",
"risk_score": 47,
@@ -18,4 +17,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_dumping_detected.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_dumping_detected.json
index fdd875e95b3d..8c2c5f32feab 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_dumping_detected.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_dumping_detected.json
@@ -6,7 +6,6 @@
],
"interval": "10m",
"language": "kuery",
- "max_signals": 100,
"name": "Credential Dumping - Detected - Elastic Endpoint",
"query": "event.kind:alert and event.module:endgame and event.action:cred_theft_event and endgame.metadata.type:detection",
"risk_score": 73,
@@ -18,4 +17,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_dumping_prevented.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_dumping_prevented.json
index 8ed63c55ef21..6a96da3218bf 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_dumping_prevented.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_dumping_prevented.json
@@ -6,7 +6,6 @@
],
"interval": "10m",
"language": "kuery",
- "max_signals": 100,
"name": "Credential Dumping - Prevented - Elastic Endpoint",
"query": "event.kind:alert and event.module:endgame and event.action:cred_theft_event and endgame.metadata.type:prevention",
"risk_score": 47,
@@ -18,4 +17,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_manipulation_detected.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_manipulation_detected.json
index 98c4e5341d9e..954e35ccd644 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_manipulation_detected.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_manipulation_detected.json
@@ -6,7 +6,6 @@
],
"interval": "10m",
"language": "kuery",
- "max_signals": 100,
"name": "Credential Manipulation - Detected - Elastic Endpoint",
"query": "event.kind:alert and event.module:endgame and event.action:token_manipulation_event and endgame.metadata.type:detection",
"risk_score": 73,
@@ -18,4 +17,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_manipulation_prevented.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_manipulation_prevented.json
index 4234e3d95579..0de35891a3e8 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_manipulation_prevented.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_cred_manipulation_prevented.json
@@ -6,7 +6,6 @@
],
"interval": "10m",
"language": "kuery",
- "max_signals": 100,
"name": "Credential Manipulation - Prevented - Elastic Endpoint",
"query": "event.kind:alert and event.module:endgame and event.action:token_manipulation_event and endgame.metadata.type:prevention",
"risk_score": 47,
@@ -18,4 +17,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_exploit_detected.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_exploit_detected.json
index 9971075d7e61..3652b7068ecd 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_exploit_detected.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_exploit_detected.json
@@ -6,7 +6,6 @@
],
"interval": "10m",
"language": "kuery",
- "max_signals": 100,
"name": "Exploit - Detected - Elastic Endpoint",
"query": "event.kind:alert and event.module:endgame and event.action:exploit_event and endgame.metadata.type:detection",
"risk_score": 73,
@@ -18,4 +17,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_exploit_prevented.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_exploit_prevented.json
index 233552fc1de1..dbc910c3002a 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_exploit_prevented.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_exploit_prevented.json
@@ -6,7 +6,6 @@
],
"interval": "10m",
"language": "kuery",
- "max_signals": 100,
"name": "Exploit - Prevented - Elastic Endpoint",
"query": "event.kind:alert and event.module:endgame and event.action:exploit_event and endgame.metadata.type:prevention",
"risk_score": 47,
@@ -18,4 +17,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_malware_detected.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_malware_detected.json
index 64d686fb984c..efe2806532be 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_malware_detected.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_malware_detected.json
@@ -6,7 +6,6 @@
],
"interval": "10m",
"language": "kuery",
- "max_signals": 100,
"name": "Malware - Detected - Elastic Endpoint",
"query": "event.kind:alert and event.module:endgame and event.action:file_classification_event and endgame.metadata.type:detection",
"risk_score": 99,
@@ -18,4 +17,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_malware_prevented.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_malware_prevented.json
index 72f2134f23ab..51028b9dbeeb 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_malware_prevented.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_malware_prevented.json
@@ -6,7 +6,6 @@
],
"interval": "10m",
"language": "kuery",
- "max_signals": 100,
"name": "Malware - Prevented - Elastic Endpoint",
"query": "event.kind:alert and event.module:endgame and event.action:file_classification_event and endgame.metadata.type:prevention",
"risk_score": 73,
@@ -18,4 +17,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_permission_theft_detected.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_permission_theft_detected.json
index 3755dd4cd5da..c30ca0632f41 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_permission_theft_detected.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_permission_theft_detected.json
@@ -6,7 +6,6 @@
],
"interval": "10m",
"language": "kuery",
- "max_signals": 100,
"name": "Permission Theft - Detected - Elastic Endpoint",
"query": "event.kind:alert and event.module:endgame and event.action:token_protection_event and endgame.metadata.type:detection",
"risk_score": 73,
@@ -18,4 +17,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_permission_theft_prevented.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_permission_theft_prevented.json
index d86940758637..ed0c71425474 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_permission_theft_prevented.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_permission_theft_prevented.json
@@ -6,7 +6,6 @@
],
"interval": "10m",
"language": "kuery",
- "max_signals": 100,
"name": "Permission Theft - Prevented - Elastic Endpoint",
"query": "event.kind:alert and event.module:endgame and event.action:token_protection_event and endgame.metadata.type:prevention",
"risk_score": 47,
@@ -18,4 +17,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_process_injection_detected.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_process_injection_detected.json
index 1078cf69394e..63b008849487 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_process_injection_detected.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_process_injection_detected.json
@@ -6,7 +6,6 @@
],
"interval": "10m",
"language": "kuery",
- "max_signals": 100,
"name": "Process Injection - Detected - Elastic Endpoint",
"query": "event.kind:alert and event.module:endgame and event.action:kernel_shellcode_event and endgame.metadata.type:detection",
"risk_score": 73,
@@ -18,4 +17,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_process_injection_prevented.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_process_injection_prevented.json
index 8b68fc6925f9..135b4a95e800 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_process_injection_prevented.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_process_injection_prevented.json
@@ -6,7 +6,6 @@
],
"interval": "10m",
"language": "kuery",
- "max_signals": 100,
"name": "Process Injection - Prevented - Elastic Endpoint",
"query": "event.kind:alert and event.module:endgame and event.action:kernel_shellcode_event and endgame.metadata.type:prevention",
"risk_score": 47,
@@ -18,4 +17,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_ransomware_detected.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_ransomware_detected.json
index a332c7011e94..d4042a5e6b9e 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_ransomware_detected.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_ransomware_detected.json
@@ -6,7 +6,6 @@
],
"interval": "10m",
"language": "kuery",
- "max_signals": 100,
"name": "Ransomware - Detected - Elastic Endpoint",
"query": "event.kind:alert and event.module:endgame and event.action:ransomware_event and endgame.metadata.type:detection",
"risk_score": 99,
@@ -18,4 +17,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_ransomware_prevented.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_ransomware_prevented.json
index 087c91d2105c..befdf611da22 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_ransomware_prevented.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security_ransomware_prevented.json
@@ -6,7 +6,6 @@
],
"interval": "10m",
"language": "kuery",
- "max_signals": 100,
"name": "Ransomware - Prevented - Elastic Endpoint",
"query": "event.kind:alert and event.module:endgame and event.action:ransomware_event and endgame.metadata.type:prevention",
"risk_score": 73,
@@ -18,4 +17,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_adding_the_hidden_file_attribute_with_via_attribexe.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_adding_the_hidden_file_attribute_with_via_attribexe.json
index 43aead33925c..6c9b54b8ddb0 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_adding_the_hidden_file_attribute_with_via_attribexe.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_adding_the_hidden_file_attribute_with_via_attribexe.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Adding Hidden File Attribute via Attrib",
- "query": " event.action:\"Process Create (rule: ProcessCreate)\" and process.name:\"attrib.exe\" and process.args:\"+h\"",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:attrib.exe and process.args:+h",
"risk_score": 21,
"rule_id": "4630d948-40d4-4cef-ac69-4002e29bc3db",
"severity": "low",
@@ -48,4 +47,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_adobe_hijack_persistence.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_adobe_hijack_persistence.json
index 8b8c51009326..3b4d2bc04021 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_adobe_hijack_persistence.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_adobe_hijack_persistence.json
@@ -4,7 +4,6 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Adobe Hijack Persistence",
"query": "file.path:(\"C:\\Program Files (x86)\\Adobe\\Acrobat Reader DC\\Reader\\AcroCEF\\RdrCEF.exe\" or \"C:\\Program Files\\Adobe\\Acrobat Reader DC\\Reader\\AcroCEF\\RdrCEF.exe\") and event.action:\"File created (rule: FileCreate)\" and not process.name:msiexec.exe",
"risk_score": 21,
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 2
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_clearing_windows_event_logs.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_clearing_windows_event_logs.json
index 135e81148475..244d329cc4bb 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_clearing_windows_event_logs.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_clearing_windows_event_logs.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Clearing Windows Event Logs",
- "query": "event.action:\"Process Create (rule: ProcessCreate)\" and (process.name:\"wevtutil.exe\" and process.args:\"cl\") or (process.name:\"powershell.exe\" and process.args:\"Clear-EventLog\")",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:wevtutil.exe and process.args:cl or process.name:powershell.exe and process.args:Clear-EventLog",
"risk_score": 21,
"rule_id": "d331bbe2-6db4-4941-80a5-8270db72eb61",
"severity": "low",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_delete_volume_usn_journal_with_fsutil.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_delete_volume_usn_journal_with_fsutil.json
index 815e2abd0fc9..408754281658 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_delete_volume_usn_journal_with_fsutil.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_delete_volume_usn_journal_with_fsutil.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Delete Volume USN Journal with Fsutil",
- "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:\"fsutil.exe\" and process.args:(\"usn\" and \"deletejournal\")",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:fsutil.exe and process.args:(deletejournal and usn)",
"risk_score": 21,
"rule_id": "f675872f-6d85-40a3-b502-c0d2ef101e92",
"severity": "low",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_deleting_backup_catalogs_with_wbadmin.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_deleting_backup_catalogs_with_wbadmin.json
index d990e071b212..eca06723e68b 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_deleting_backup_catalogs_with_wbadmin.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_deleting_backup_catalogs_with_wbadmin.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Deleting Backup Catalogs with Wbadmin",
- "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:\"wbadmin.exe\" and process.args:(\"delete\" and \"catalog\")",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:wbadmin.exe and process.args:(catalog and delete)",
"risk_score": 21,
"rule_id": "581add16-df76-42bb-af8e-c979bfb39a59",
"severity": "low",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_direct_outbound_smb_connection.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_direct_outbound_smb_connection.json
index 9d1cebb32c86..e37c877c6288 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_direct_outbound_smb_connection.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_direct_outbound_smb_connection.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Direct Outbound SMB Connection",
- "query": " event.action:\"Network connection detected (rule: NetworkConnect)\" and destination.port:445 and not process.pid:4 and not destination.ip:(\"127.0.0.1\" or \"::1\")",
+ "query": "event.action:\"Network connection detected (rule: NetworkConnect)\" and destination.port:445 and not process.pid:4 and not destination.ip:(127.0.0.1 or \"::1\")",
"risk_score": 47,
"rule_id": "c82c7d8f-fb9e-4874-a4bd-fd9e3f9becf1",
"severity": "medium",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_disable_windows_firewall_rules_with_netsh.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_disable_windows_firewall_rules_with_netsh.json
index 7ead979f27bb..f6b4bc67ed9b 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_disable_windows_firewall_rules_with_netsh.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_disable_windows_firewall_rules_with_netsh.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Disable Windows Firewall Rules via Netsh",
- "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:\"netsh.exe\" and process.args:(\"firewall\" and \"set\" and \"disable\") or process.args:(\"advfirewall\" and \"state\" and \"off\")",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:netsh.exe and process.args:(disable and firewall and set) or process.args:(advfirewall and off and state)",
"risk_score": 47,
"rule_id": "4b438734-3793-4fda-bd42-ceeada0be8f9",
"severity": "medium",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_encoding_or_decoding_files_via_certutil.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_encoding_or_decoding_files_via_certutil.json
index 2cb92f0a26c9..38162889737f 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_encoding_or_decoding_files_via_certutil.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_encoding_or_decoding_files_via_certutil.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Encoding or Decoding Files via CertUtil",
- "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:\"certutil.exe\" and process.args:(\"-encode\" or \"/encode\" or \"-decode\" or \"/decode\")",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:certutil.exe and process.args:(-decode or -encode or /decode or /encode)",
"risk_score": 47,
"rule_id": "fd70c98a-c410-42dc-a2e3-761c71848acf",
"severity": "medium",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_local_scheduled_task_commands.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_local_scheduled_task_commands.json
index e7f46b46c2ce..42007f153bd5 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_local_scheduled_task_commands.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_local_scheduled_task_commands.json
@@ -7,9 +7,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Local Scheduled Task Commands",
- "query": " event.action:\"Process Create (rule: ProcessCreate)\" and process.name:schtasks.exe and process.args:(\"/create\" or \"-create\" or \"/S\" or \"-s\" or \"/run\" or \"-run\" or \"/change\" or \"-change\")",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:schtasks.exe and process.args:(-change or -create or -run or -s or /S or /change or /create or /run)",
"risk_score": 21,
"rule_id": "afcce5ad-65de-4ed2-8516-5e093d3ac99a",
"severity": "low",
@@ -36,4 +35,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_local_service_commands.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_local_service_commands.json
index b018435ea021..9559baabe0e4 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_local_service_commands.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_local_service_commands.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Local Service Commands",
- "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:sc.exe and process.args:(\"create\" or \"config\" or \"failure\" or \"start\")",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:sc.exe and process.args:(config or create or failure or start)",
"risk_score": 21,
"rule_id": "e8571d5f-bea1-46c2-9f56-998de2d3ed95",
"severity": "low",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_msbuild_making_network_connections.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_msbuild_making_network_connections.json
index 7d84e0bda06e..3e34aacf605c 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_msbuild_making_network_connections.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_msbuild_making_network_connections.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "MsBuild Making Network Connections",
- "query": " event.action:\"Network connection detected (rule: NetworkConnect)\" and process.name:MSBuild.exe and not destination.ip:(\"127.0.0.1\" or \"::1\")",
+ "query": "event.action:\"Network connection detected (rule: NetworkConnect)\" and process.name:MSBuild.exe and not destination.ip:(127.0.0.1 or \"::1\")",
"risk_score": 47,
"rule_id": "0e79980b-4250-4a50-a509-69294c14e84b",
"severity": "medium",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_mshta_making_network_connections.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_mshta_making_network_connections.json
index 44141b08fb8f..769614e8faf5 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_mshta_making_network_connections.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_mshta_making_network_connections.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Network Connection via Mshta",
- "query": "event.action:\"Network connection detected (rule: NetworkConnect)\" and process.name:\"mshta.exe\"",
+ "query": "event.action:\"Network connection detected (rule: NetworkConnect)\" and process.name:mshta.exe",
"references": [
"https://www.fireeye.com/blog/threat-research/2017/05/cyber-espionage-apt32.html"
],
@@ -36,4 +35,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_psexec_lateral_movement_command.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_psexec_lateral_movement_command.json
index 580f73c25a4a..ac170665042f 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_psexec_lateral_movement_command.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_psexec_lateral_movement_command.json
@@ -7,9 +7,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "PsExec Network Connection",
- "query": "process.name:PsExec.exe and event.action:\"Network connection detected (rule: NetworkConnect)\" ",
+ "query": "process.name:PsExec.exe and event.action:\"Network connection detected (rule: NetworkConnect)\"",
"risk_score": 21,
"rule_id": "55d551c6-333b-4665-ab7e-5d14a59715ce",
"severity": "low",
@@ -51,4 +50,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_suspicious_ms_office_child_process.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_suspicious_ms_office_child_process.json
index 95aabc49b530..95c9c6b72f8f 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_suspicious_ms_office_child_process.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_suspicious_ms_office_child_process.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Suspicious MS Office Child Process",
- "query": " event.action:\"Process Create (rule: ProcessCreate)\" and process.parent.name:(\"winword.exe\" or \"excel.exe\" or \"powerpnt.exe\" or \"eqnedt32.exe\" or \"fltldr.exe\" or \"mspub.exe\" or \"msaccess.exe\") and process.name:(\"arp.exe\" or \"dsquery.exe\" or \"dsget.exe\" or \"gpresult.exe\" or \"hostname.exe\" or \"ipconfig.exe\" or \"nbtstat.exe\" or \"net.exe\" or \"net1.exe\" or \"netsh.exe\" or \"netstat.exe\" or \"nltest.exe\" or \"ping.exe\" or \"qprocess.exe\" or \"quser.exe\" or \"qwinsta.exe\" or \"reg.exe\" or \"sc.exe\" or \"systeminfo.exe\" or \"tasklist.exe\" or \"tracert.exe\" or \"whoami.exe\" or \"bginfo.exe\" or \"cdb.exe\" or \"cmstp.exe\" or \"csi.exe\" or \"dnx.exe\" or \"fsi.exe\" or \"ieexec.exe\" or \"iexpress.exe\" or \"installutil.exe\" or \"Microsoft.Workflow.Compiler.exe\" or \"msbuild.exe\" or \"mshta.exe\" or \"msxsl.exe\" or \"odbcconf.exe\" or \"rcsi.exe\" or \"regsvr32.exe\" or \"xwizard.exe\" or \"atbroker.exe\" or \"forfiles.exe\" or \"schtasks.exe\" or \"regasm.exe\" or \"regsvcs.exe\" or \"cmd.exe\" or \"cscript.exe\" or \"powershell.exe\" or \"pwsh.exe\" or \"wmic.exe\" or \"wscript.exe\" or \"bitsadmin.exe\" or \"certutil.exe\" or \"ftp.exe\") ",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.parent.name:(eqnedt32.exe or excel.exe or fltldr.exe or msaccess.exe or mspub.exe or powerpnt.exe or winword.exe) and process.name:(Microsoft.Workflow.Compiler.exe or arp.exe or atbroker.exe or bginfo.exe or bitsadmin.exe or cdb.exe or certutil.exe or cmd.exe or cmstp.exe or cscript.exe or csi.exe or dnx.exe or dsget.exe or dsquery.exe or forfiles.exe or fsi.exe or ftp.exe or gpresult.exe or hostname.exe or ieexec.exe or iexpress.exe or installutil.exe or ipconfig.exe or mshta.exe or msxsl.exe or nbtstat.exe or net.exe or net1.exe or netsh.exe or netstat.exe or nltest.exe or odbcconf.exe or ping.exe or powershell.exe or pwsh.exe or qprocess.exe or quser.exe or qwinsta.exe or rcsi.exe or reg.exe or regasm.exe or regsvcs.exe or regsvr32.exe or sc.exe or schtasks.exe or systeminfo.exe or tasklist.exe or tracert.exe or whoami.exe or wmic.exe or wscript.exe or xwizard.exe)",
"risk_score": 21,
"rule_id": "a624863f-a70d-417f-a7d2-7a404638d47f",
"severity": "low",
@@ -32,5 +31,5 @@
}
],
"type": "query",
- "version": 1
-}
+ "version": 2
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_suspicious_ms_outlook_child_process.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_suspicious_ms_outlook_child_process.json
index f31228d0130f..7f6c9257fabf 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_suspicious_ms_outlook_child_process.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_suspicious_ms_outlook_child_process.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Suspicious MS Outlook Child Process",
- "query": " event.action:\"Process Create (rule: ProcessCreate)\" and process.parent.name:\"outlook.exe\" and process.name:(\"arp.exe\" or \"dsquery.exe\" or \"dsget.exe\" or \"gpresult.exe\" or \"hostname.exe\" or \"ipconfig.exe\" or \"nbtstat.exe\" or \"net.exe\" or \"net1.exe\" or \"netsh.exe\" or \"netstat.exe\" or \"nltest.exe\" or \"ping.exe\" or \"qprocess.exe\" or \"quser.exe\" or \"qwinsta.exe\" or \"reg.exe\" or \"sc.exe\" or \"systeminfo.exe\" or \"tasklist.exe\" or \"tracert.exe\" or \"whoami.exe\" or \"bginfo.exe\" or \"cdb.exe\" or \"cmstp.exe\" or \"csi.exe\" or \"dnx.exe\" or \"fsi.exe\" or \"ieexec.exe\" or \"iexpress.exe\" or \"installutil.exe\" or \"Microsoft.Workflow.Compiler.exe\" or \"msbuild.exe\" or \"mshta.exe\" or \"msxsl.exe\" or \"odbcconf.exe\" or \"rcsi.exe\" or \"regsvr32.exe\" or \"xwizard.exe\" or \"atbroker.exe\" or \"forfiles.exe\" or \"schtasks.exe\" or \"regasm.exe\" or \"regsvcs.exe\" or \"cmd.exe\" or \"cscript.exe\" or \"powershell.exe\" or \"pwsh.exe\" or \"wmic.exe\" or \"wscript.exe\" or \"bitsadmin.exe\" or \"certutil.exe\" or \"ftp.exe\") ",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.parent.name:outlook.exe and process.name:(Microsoft.Workflow.Compiler.exe or arp.exe or atbroker.exe or bginfo.exe or bitsadmin.exe or cdb.exe or certutil.exe or cmd.exe or cmstp.exe or cscript.exe or csi.exe or dnx.exe or dsget.exe or dsquery.exe or forfiles.exe or fsi.exe or ftp.exe or gpresult.exe or hostname.exe or ieexec.exe or iexpress.exe or installutil.exe or ipconfig.exe or mshta.exe or msxsl.exe or nbtstat.exe or net.exe or net1.exe or netsh.exe or netstat.exe or nltest.exe or odbcconf.exe or ping.exe or powershell.exe or pwsh.exe or qprocess.exe or quser.exe or qwinsta.exe or rcsi.exe or reg.exe or regasm.exe or regsvcs.exe or regsvr32.exe or sc.exe or schtasks.exe or systeminfo.exe or tasklist.exe or tracert.exe or whoami.exe or wmic.exe or wscript.exe or xwizard.exe)",
"risk_score": 21,
"rule_id": "32f4675e-6c49-4ace-80f9-97c9259dca2e",
"severity": "low",
@@ -32,5 +31,5 @@
}
],
"type": "query",
- "version": 1
-}
+ "version": 2
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_system_shells_via_services.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_system_shells_via_services.json
index a38232f37843..1c001caa1539 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_system_shells_via_services.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_system_shells_via_services.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "System Shells via Services",
- "query": " event.action:\"Process Create (rule: ProcessCreate)\" and process.parent.name:\"services.exe\" and process.name:(\"cmd.exe\" or \"powershell.exe\")",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.parent.name:services.exe and process.name:(cmd.exe or powershell.exe)",
"risk_score": 47,
"rule_id": "0022d47d-39c7-4f69-a232-4fe9dc7a3acd",
"severity": "medium",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_unusual_network_connection_via_rundll32.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_unusual_network_connection_via_rundll32.json
index 820c69cb3c80..0165f4d7512e 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_unusual_network_connection_via_rundll32.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_unusual_network_connection_via_rundll32.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Unusual Network Connection via RunDLL32",
- "query": "process.name:rundll32.exe and event.action:\"Network connection detected (rule: NetworkConnect)\" and not destination.ip:10.0.0.0/8 and not destination.ip:172.16.0.0/12 and not destination.ip:192.168.0.0/16",
+ "query": "process.name:rundll32.exe and event.action:\"Network connection detected (rule: NetworkConnect)\" and not destination.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)",
"risk_score": 21,
"rule_id": "52aaab7b-b51c-441a-89ce-4387b3aea886",
"severity": "low",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_unusual_parentchild_relationship.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_unusual_parentchild_relationship.json
index 21d3d2741378..0b4bf9ff3294 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_unusual_parentchild_relationship.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_unusual_parentchild_relationship.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
- "name": "Unusual Parent-Child Relationship ",
- "query": " event.action:\"Process Create (rule: ProcessCreate)\" and process.parent.executable:* and ( (process.name:\"smss.exe\" and not process.parent.name:(\"System\" or \"smss.exe\")) or (process.name:\"csrss.exe\" and not process.parent.name:(\"smss.exe\" or \"svchost.exe\")) or (process.name:\"wininit.exe\" and not process.parent.name:\"smss.exe\") or (process.name:\"winlogon.exe\" and not process.parent.name:\"smss.exe\") or (process.name:\"lsass.exe\" and not process.parent.name:\"wininit.exe\") or (process.name:\"LogonUI.exe\" and not process.parent.name:(\"winlogon.exe\" or \"wininit.exe\")) or (process.name:\"services.exe\" and not process.parent.name:\"wininit.exe\") or (process.name:\"svchost.exe\" and not process.parent.name:(\"services.exe\" or \"MsMpEng.exe\")) or (process.name:\"spoolsv.exe\" and not process.parent.name:\"services.exe\") or (process.name:\"taskhost.exe\" and not process.parent.name:(\"services.exe\" or \"svchost.exe\")) or (process.name:\"taskhostw.exe\" and not process.parent.name:(\"services.exe\" or \"svchost.exe\")) or (process.name:\"userinit.exe\" and not process.parent.name:(\"dwm.exe\" or \"winlogon.exe\")) )",
+ "name": "Unusual Parent-Child Relationship",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.parent.executable:* and (process.name:smss.exe and not process.parent.name:(System or smss.exe) or process.name:csrss.exe and not process.parent.name:(smss.exe or svchost.exe) or process.name:wininit.exe and not process.parent.name:smss.exe or process.name:winlogon.exe and not process.parent.name:smss.exe or process.name:lsass.exe and not process.parent.name:wininit.exe or process.name:LogonUI.exe and not process.parent.name:(wininit.exe or winlogon.exe) or process.name:services.exe and not process.parent.name:wininit.exe or process.name:svchost.exe and not process.parent.name:(MsMpEng.exe or services.exe) or process.name:spoolsv.exe and not process.parent.name:services.exe or process.name:taskhost.exe and not process.parent.name:(services.exe or svchost.exe) or process.name:taskhostw.exe and not process.parent.name:(services.exe or svchost.exe) or process.name:userinit.exe and not process.parent.name:(dwm.exe or winlogon.exe))",
"risk_score": 47,
"rule_id": "35df0dd8-092d-4a83-88c1-5151a804f31b",
"severity": "medium",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_unusual_process_network_connection.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_unusual_process_network_connection.json
index ee861e19341a..2c88a2061844 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_unusual_process_network_connection.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_unusual_process_network_connection.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Unusual Process Network Connection",
- "query": " event.action:\"Network connection detected (rule: NetworkConnect)\" and process.name:(bginfo.exe or cdb.exe or cmstp.exe or csi.exe or dnx.exe or fsi.exe or ieexec.exe or iexpress.exe or Microsoft.Workflow.Compiler.exe or odbcconf.exe or rcsi.exe or xwizard.exe)",
+ "query": "event.action:\"Network connection detected (rule: NetworkConnect)\" and process.name:(Microsoft.Workflow.Compiler.exe or bginfo.exe or cdb.exe or cmstp.exe or csi.exe or dnx.exe or fsi.exe or ieexec.exe or iexpress.exe or odbcconf.exe or rcsi.exe or xwizard.exe)",
"risk_score": 21,
"rule_id": "610949a1-312f-4e04-bb55-3a79b8c95267",
"severity": "low",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_user_account_creation.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_user_account_creation.json
index 5a7aeab22454..240df3441913 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_user_account_creation.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_user_account_creation.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "User Account Creation",
- "query": " event.action:\"Process Create (rule: ProcessCreate)\" and process.name:(\"net.exe\" or \"net1.exe\") and not process.parent.name:\"net.exe\" and process.args:(\"user\" and (\"/add\" or \"/ad\")) ",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:(net.exe or net1.exe) and not process.parent.name:net.exe and process.args:(user and (/ad or /add))",
"risk_score": 21,
"rule_id": "1aa9181a-492b-4c01-8b16-fa0735786b2b",
"severity": "low",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_volume_shadow_copy_deletion_via_vssadmin.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_volume_shadow_copy_deletion_via_vssadmin.json
index 80c0dd962c09..e12c2e70138c 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_volume_shadow_copy_deletion_via_vssadmin.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_volume_shadow_copy_deletion_via_vssadmin.json
@@ -1,12 +1,11 @@
{
- "description": "Identifies use of vssadmin.exe for shadow copy deletion on endpoints. This commonly occurs in tandem with ransomware or other destructive attacks.",
+ "description": "Identifies use of vssadmin.exe for shadow copy deletion on endpoints. This commonly occurs in tandem with ransomware or other destructive attacks.",
"index": [
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Volume Shadow Copy Deletion via VssAdmin",
- "query": " event.action:\"Process Create (rule: ProcessCreate)\" and process.name:\"vssadmin.exe\" and process.args:(\"delete\" and \"shadows\") ",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:vssadmin.exe and process.args:(delete and shadows)",
"risk_score": 73,
"rule_id": "b5ea4bfe-a1b2-421f-9d47-22a75a6f2921",
"severity": "high",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_volume_shadow_copy_deletion_via_wmic.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_volume_shadow_copy_deletion_via_wmic.json
index d90aca1e2eaf..94b8846741e3 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_volume_shadow_copy_deletion_via_wmic.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_volume_shadow_copy_deletion_via_wmic.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Volume Shadow Copy Deletion via WMIC",
- "query": " event.action:\"Process Create (rule: ProcessCreate)\" and process.name:\"WMIC.exe\" and process.args:(\"shadowcopy\" and \"delete\")",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:WMIC.exe and process.args:(delete and shadowcopy)",
"risk_score": 73,
"rule_id": "dc9c1f74-dac3-48e3-b47f-eb79db358f57",
"severity": "high",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_windows_script_executing_powershell.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_windows_script_executing_powershell.json
index 8f6e97cdd7bd..b0a754a662c0 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_windows_script_executing_powershell.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/eql_windows_script_executing_powershell.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Windows Script Executing PowerShell",
- "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.parent.name:(\"wscript.exe\" or \"cscript.exe\") and process.name:\"powershell.exe\"",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.parent.name:(cscript.exe or wscript.exe) and process.name:powershell.exe",
"risk_score": 21,
"rule_id": "f545ff26-3c94-4fd0-bd33-3c7f95a3a0fc",
"severity": "low",
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/index.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/index.ts
index d9841948f35a..c24f5bb64ef5 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/index.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/index.ts
@@ -47,58 +47,96 @@ import rule37 from './eql_user_account_creation.json';
import rule38 from './eql_volume_shadow_copy_deletion_via_vssadmin.json';
import rule39 from './eql_volume_shadow_copy_deletion_via_wmic.json';
import rule40 from './eql_windows_script_executing_powershell.json';
-import rule41 from './linux_hping_activity.json';
-import rule42 from './linux_iodine_activity.json';
-import rule43 from './linux_kernel_module_activity.json';
-import rule44 from './linux_mknod_activity.json';
-import rule45 from './linux_netcat_network_connection.json';
-import rule46 from './linux_nmap_activity.json';
-import rule47 from './linux_nping_activity.json';
-import rule48 from './linux_process_started_in_temp_directory.json';
-import rule49 from './linux_shell_activity_by_web_server.json';
-import rule50 from './linux_socat_activity.json';
-import rule51 from './linux_strace_activity.json';
-import rule52 from './linux_tcpdump_activity.json';
-import rule53 from './linux_whoami_commmand.json';
-import rule54 from './network_dns_directly_to_the_internet.json';
-import rule55 from './network_ftp_file_transfer_protocol_activity_to_the_internet.json';
-import rule56 from './network_irc_internet_relay_chat_protocol_activity_to_the_internet.json';
-import rule57 from './network_nat_traversal_port_activity.json';
-import rule58 from './network_port_26_activity.json';
-import rule59 from './network_port_8000_activity_to_the_internet.json';
-import rule60 from './network_pptp_point_to_point_tunneling_protocol_activity.json';
-import rule61 from './network_proxy_port_activity_to_the_internet.json';
-import rule62 from './network_rdp_remote_desktop_protocol_from_the_internet.json';
-import rule63 from './network_rdp_remote_desktop_protocol_to_the_internet.json';
-import rule64 from './network_rpc_remote_procedure_call_from_the_internet.json';
-import rule65 from './network_rpc_remote_procedure_call_to_the_internet.json';
-import rule66 from './network_smb_windows_file_sharing_activity_to_the_internet.json';
-import rule67 from './network_smtp_to_the_internet.json';
-import rule68 from './network_sql_server_port_activity_to_the_internet.json';
-import rule69 from './network_ssh_secure_shell_from_the_internet.json';
-import rule70 from './network_ssh_secure_shell_to_the_internet.json';
-import rule71 from './network_telnet_port_activity.json';
-import rule72 from './network_tor_activity_to_the_internet.json';
-import rule73 from './network_vnc_virtual_network_computing_from_the_internet.json';
-import rule74 from './network_vnc_virtual_network_computing_to_the_internet.json';
-import rule75 from './null_user_agent.json';
-import rule76 from './sqlmap_user_agent.json';
-import rule77 from './windows_command_prompt_connecting_to_the_internet.json';
-import rule78 from './windows_command_shell_started_by_powershell.json';
-import rule79 from './windows_command_shell_started_by_svchost.json';
-import rule80 from './windows_defense_evasion_via_filter_manager.json';
-import rule81 from './windows_execution_via_compiled_html_file.json';
-import rule82 from './windows_execution_via_regsvr32.json';
-import rule83 from './windows_execution_via_trusted_developer_utilities.json';
-import rule84 from './windows_html_help_executable_program_connecting_to_the_internet.json';
-import rule85 from './windows_misc_lolbin_connecting_to_the_internet.json';
-import rule86 from './windows_persistence_via_application_shimming.json';
-import rule87 from './windows_priv_escalation_via_accessibility_features.json';
-import rule88 from './windows_process_discovery_via_tasklist_command.json';
-import rule89 from './windows_register_server_program_connecting_to_the_internet.json';
-import rule90 from './windows_signed_binary_proxy_execution.json';
-import rule91 from './windows_suspicious_process_started_by_a_script.json';
-import rule92 from './windows_whoami_command_activity.json';
+import rule41 from './linux_anomalous_network_activity.json';
+import rule42 from './linux_anomalous_network_port_activity.json';
+import rule43 from './linux_anomalous_network_service.json';
+import rule44 from './linux_anomalous_network_url_activity.json';
+import rule45 from './linux_anomalous_process_all_hosts.json';
+import rule46 from './linux_anomalous_user_name.json';
+import rule47 from './linux_hping_activity.json';
+import rule48 from './linux_iodine_activity.json';
+import rule49 from './linux_kernel_module_activity.json';
+import rule50 from './linux_mknod_activity.json';
+import rule51 from './linux_netcat_network_connection.json';
+import rule52 from './linux_nmap_activity.json';
+import rule53 from './linux_nping_activity.json';
+import rule54 from './linux_process_started_in_temp_directory.json';
+import rule55 from './linux_shell_activity_by_web_server.json';
+import rule56 from './linux_socat_activity.json';
+import rule57 from './linux_strace_activity.json';
+import rule58 from './linux_tcpdump_activity.json';
+import rule59 from './linux_whoami_commmand.json';
+import rule60 from './network_dns_directly_to_the_internet.json';
+import rule61 from './network_ftp_file_transfer_protocol_activity_to_the_internet.json';
+import rule62 from './network_irc_internet_relay_chat_protocol_activity_to_the_internet.json';
+import rule63 from './network_nat_traversal_port_activity.json';
+import rule64 from './network_port_26_activity.json';
+import rule65 from './network_port_8000_activity_to_the_internet.json';
+import rule66 from './network_pptp_point_to_point_tunneling_protocol_activity.json';
+import rule67 from './network_proxy_port_activity_to_the_internet.json';
+import rule68 from './network_rdp_remote_desktop_protocol_from_the_internet.json';
+import rule69 from './network_rdp_remote_desktop_protocol_to_the_internet.json';
+import rule70 from './network_rpc_remote_procedure_call_from_the_internet.json';
+import rule71 from './network_rpc_remote_procedure_call_to_the_internet.json';
+import rule72 from './network_smb_windows_file_sharing_activity_to_the_internet.json';
+import rule73 from './network_smtp_to_the_internet.json';
+import rule74 from './network_sql_server_port_activity_to_the_internet.json';
+import rule75 from './network_ssh_secure_shell_from_the_internet.json';
+import rule76 from './network_ssh_secure_shell_to_the_internet.json';
+import rule77 from './network_telnet_port_activity.json';
+import rule78 from './network_tor_activity_to_the_internet.json';
+import rule79 from './network_vnc_virtual_network_computing_from_the_internet.json';
+import rule80 from './network_vnc_virtual_network_computing_to_the_internet.json';
+import rule81 from './null_user_agent.json';
+import rule82 from './packetbeat_dns_tunneling.json';
+import rule83 from './packetbeat_rare_dns_question.json';
+import rule84 from './packetbeat_rare_server_domain.json';
+import rule85 from './packetbeat_rare_urls.json';
+import rule86 from './packetbeat_rare_user_agent.json';
+import rule87 from './rare_process_by_host_linux.json';
+import rule88 from './rare_process_by_host_windows.json';
+import rule89 from './sqlmap_user_agent.json';
+import rule90 from './suspicious_login_activity.json';
+import rule91 from './windows_anomalous_network_activity.json';
+import rule92 from './windows_anomalous_path_activity.json';
+import rule93 from './windows_anomalous_process_all_hosts.json';
+import rule94 from './windows_anomalous_process_creation.json';
+import rule95 from './windows_anomalous_script.json';
+import rule96 from './windows_anomalous_service.json';
+import rule97 from './windows_anomalous_user_name.json';
+import rule98 from './windows_certutil_network_connection.json';
+import rule99 from './windows_command_prompt_connecting_to_the_internet.json';
+import rule100 from './windows_command_shell_started_by_powershell.json';
+import rule101 from './windows_command_shell_started_by_svchost.json';
+import rule102 from './windows_credential_dumping_msbuild.json';
+import rule103 from './windows_cve_2020_0601.json';
+import rule104 from './windows_defense_evasion_via_filter_manager.json';
+import rule105 from './windows_execution_msbuild_started_by_office_app.json';
+import rule106 from './windows_execution_msbuild_started_by_script.json';
+import rule107 from './windows_execution_msbuild_started_by_system_process.json';
+import rule108 from './windows_execution_msbuild_started_renamed.json';
+import rule109 from './windows_execution_msbuild_started_unusal_process.json';
+import rule110 from './windows_execution_via_compiled_html_file.json';
+import rule111 from './windows_execution_via_net_com_assemblies.json';
+import rule112 from './windows_execution_via_regsvr32.json';
+import rule113 from './windows_execution_via_trusted_developer_utilities.json';
+import rule114 from './windows_html_help_executable_program_connecting_to_the_internet.json';
+import rule115 from './windows_injection_msbuild.json';
+import rule116 from './windows_misc_lolbin_connecting_to_the_internet.json';
+import rule117 from './windows_modification_of_boot_config.json';
+import rule118 from './windows_msxsl_network.json';
+import rule119 from './windows_net_command_system_account.json';
+import rule120 from './windows_persistence_via_application_shimming.json';
+import rule121 from './windows_priv_escalation_via_accessibility_features.json';
+import rule122 from './windows_process_discovery_via_tasklist_command.json';
+import rule123 from './windows_rare_user_runas_event.json';
+import rule124 from './windows_rare_user_type10_remote_login.json';
+import rule125 from './windows_register_server_program_connecting_to_the_internet.json';
+import rule126 from './windows_signed_binary_proxy_execution.json';
+import rule127 from './windows_suspicious_pdf_reader.json';
+import rule128 from './windows_suspicious_process_started_by_a_script.json';
+import rule129 from './windows_uac_bypass_event_viewer.json';
+import rule130 from './windows_whoami_command_activity.json';
export const rawRules = [
rule1,
rule2,
@@ -192,4 +230,42 @@ export const rawRules = [
rule90,
rule91,
rule92,
+ rule93,
+ rule94,
+ rule95,
+ rule96,
+ rule97,
+ rule98,
+ rule99,
+ rule100,
+ rule101,
+ rule102,
+ rule103,
+ rule104,
+ rule105,
+ rule106,
+ rule107,
+ rule108,
+ rule109,
+ rule110,
+ rule111,
+ rule112,
+ rule113,
+ rule114,
+ rule115,
+ rule116,
+ rule117,
+ rule118,
+ rule119,
+ rule120,
+ rule121,
+ rule122,
+ rule123,
+ rule124,
+ rule125,
+ rule126,
+ rule127,
+ rule128,
+ rule129,
+ rule130,
];
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_network_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_network_activity.json
new file mode 100644
index 000000000000..1123c1161c4c
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_network_activity.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "Identifies Linux processes that do not usually use the network but have unexpected network activity, which can indicate command-and-control, lateral movement, persistence, or data exfiltration activity. A process with unusual network activity can denote process exploitation or injection, where the process is used to run persistence mechanisms that allow a malicious actor remote access or control of the host, data exfiltration, and execution of unauthorized network applications.",
+ "false_positives": [
+ "A newly installed program or one that rarely uses the network could trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "linux_anomalous_network_activity_ecs",
+ "name": "Unusual Linux Network Activity",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "52afbdc5-db15-485e-bc24-f5707f820c4b",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Linux",
+ "ML"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_network_port_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_network_port_activity.json
new file mode 100644
index 000000000000..19dd643945b1
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_network_port_activity.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "Identifies unusual destination port activity that can indicate command-and-control, persistence mechanism, or data exfiltration activity. Rarely used destination port activity is generally unusual in Linux fleets, and can indicate unauthorized access or threat actor activity.",
+ "false_positives": [
+ "A newly installed program or one that rarely uses the network could trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "linux_anomalous_network_port_activity_ecs",
+ "name": "Unusual Linux Network Port Activity",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "3c7e32e6-6104-46d9-a06e-da0f8b5795a0",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Linux",
+ "ML"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_network_service.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_network_service.json
new file mode 100644
index 000000000000..e2e5803618d0
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_network_service.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "Identifies unusual listening ports on Linux instances that can indicate execution of unauthorized services, backdoors, or persistence mechanisms.",
+ "false_positives": [
+ "A newly installed program or one that rarely uses the network could trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "linux_anomalous_network_service",
+ "name": "Unusual Linux Network Service",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "52afbdc5-db15-596e-bc35-f5707f820c4b",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Linux",
+ "ML"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_network_url_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_network_url_activity.json
new file mode 100644
index 000000000000..40dd2e76c721
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_network_url_activity.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "A machine learning job detected an unusual web URL request from a Linux host, which can indicate malware delivery and execution. Wget and cURL are commonly used by Linux programs to download code and data. Most of the time, their usage is entirely normal. Generally, because they use a list of URLs, they repeatedly download from the same locations. However, Wget and cURL are sometimes used to deliver Linux exploit payloads, and threat actors use these tools to download additional software and code. For these reasons, unusual URLs can indicate unauthorized downloads or threat activity.",
+ "false_positives": [
+ "A new and unusual program or artifact download in the course of software upgrades, debugging, or troubleshooting could trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "linux_anomalous_network_url_activity_ecs",
+ "name": "Unusual Linux Web Activity",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "52afbdc5-db15-485e-bc35-f5707f820c4c",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Linux",
+ "ML"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_process_all_hosts.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_process_all_hosts.json
new file mode 100644
index 000000000000..6bac2f25fd7d
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_process_all_hosts.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "Searches for rare processes running on multiple Linux hosts in an entire fleet or network. This reduces the detection of false positives since automated maintenance processes usually only run occasionally on a single machine but are common to all or many hosts in a fleet.",
+ "false_positives": [
+ "A newly installed program or one that runs rarely as part of a monthly or quarterly workflow could trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "linux_anomalous_process_all_hosts_ecs",
+ "name": "Anomalous Process For a Linux Population",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "647fc812-7996-4795-8869-9c4ea595fe88",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Linux",
+ "ML"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_user_name.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_user_name.json
new file mode 100644
index 000000000000..8b7e6c89482f
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_anomalous_user_name.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "A machine learning job detected activity for a username that is not normally active, which can indicate unauthorized changes, activity by unauthorized users, lateral movement, or compromised credentials. In many organizations, new usernames are not often created apart from specific types of system activities, such as creating new accounts for new employees. These user accounts quickly become active and routine. Events from rarely used usernames can point to suspicious activity. Additionally, automated Linux fleets tend to see activity from rarely used usernames only when personnel log in to make authorized or unauthorized changes, or threat actors have acquired credentials and log in for malicious purposes. Unusual usernames can also indicate pivoting, where compromised credentials are used to try and move laterally from one host to another.",
+ "false_positives": [
+ "Uncommon user activity can be due to an engineer logging onto a server instance in order to perform manual troubleshooting or reconfiguration."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "linux_anomalous_user_name_ecs",
+ "name": "Unusual Linux Username",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "b347b919-665f-4aac-b9e8-68369bf2340c",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Linux",
+ "ML"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_hping_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_hping_activity.json
index c4b14389c0f7..bb8e8983661e 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_hping_activity.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_hping_activity.json
@@ -7,9 +7,8 @@
"auditbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Hping Process Activity",
- "query": "process.name: (hping3 or hping2 or hping) and event.action:executed",
+ "query": "process.name:(hping or hping2 or hping3) and event.action:executed",
"references": [
"https://en.wikipedia.org/wiki/Hping"
],
@@ -22,4 +21,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_iodine_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_iodine_activity.json
index b8455a4d2b21..4e49702855a7 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_iodine_activity.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_iodine_activity.json
@@ -7,9 +7,8 @@
"auditbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Potential DNS Tunneling via Iodine",
- "query": "process.name: (iodine or iodined) and event.action:executed",
+ "query": "process.name:(iodine or iodined) and event.action:executed",
"references": [
"https://code.kryo.se/iodine/"
],
@@ -22,4 +21,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_kernel_module_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_kernel_module_activity.json
index f1d12de67448..cf8cd72b7aa6 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_kernel_module_activity.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_kernel_module_activity.json
@@ -7,9 +7,8 @@
"auditbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Persistence via Kernel Module Modification",
- "query": "process.name: (insmod or kmod or modprobe or rmod) and event.action:executed",
+ "query": "process.name:(insmod or kmod or modprobe or rmod) and event.action:executed",
"references": [
"https://www.hackers-arise.com/single-post/2017/11/03/Linux-for-Hackers-Part-10-Loadable-Kernel-Modules-LKM"
],
@@ -39,4 +38,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_mknod_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_mknod_activity.json
index b0d4c29dc00d..3bd3848c0758 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_mknod_activity.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_mknod_activity.json
@@ -1,5 +1,5 @@
{
- "description": "The Linux mknod program is sometimes used in the command payload of a remote command injection (RCI) and other exploits. It is used to export a command shell when the traditional version of netcat is not available to the payload.",
+ "description": "The Linux mknod program is sometimes used in the command payload of a remote command injection (RCI) and other exploits. It is used to export a command shell when the traditional version of netcat is not available to the payload.",
"false_positives": [
"Mknod is a Linux system program. Some normal use of this program, at varying levels of frequency, may originate from scripts, automation tools, and frameworks. Usage by web servers is more likely to be suspicious."
],
@@ -7,9 +7,8 @@
"auditbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Mknod Process Activity",
- "query": "process.name: mknod and event.action:executed",
+ "query": "process.name:mknod and event.action:executed",
"references": [
"https://pen-testing.sans.org/blog/2013/05/06/netcat-without-e-no-problem"
],
@@ -22,4 +21,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_netcat_network_connection.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_netcat_network_connection.json
index 6ab1c1285c0d..cd523b6594cc 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_netcat_network_connection.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_netcat_network_connection.json
@@ -7,9 +7,8 @@
"auditbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Netcat Network Activity",
- "query": "process.name: (nc or ncat or netcat or netcat.openbsd or netcat.traditional) and event.action: (connected-to or bound-socket or socket_opened)",
+ "query": "process.name:(nc or ncat or netcat or netcat.openbsd or netcat.traditional) and event.action:(bound-socket or connected-to or socket_opened)",
"references": [
"http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet",
"https://www.sans.org/security-resources/sec560/netcat_cheat_sheet_v1.pdf",
@@ -24,4 +23,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_nmap_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_nmap_activity.json
index 5d7169219a6f..604cfa172fd8 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_nmap_activity.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_nmap_activity.json
@@ -1,5 +1,5 @@
{
- "description": "Nmap was executed on a Linux host. Nmap is a FOSS tool for network scanning and security testing. It can map and discover networks, and identify listening services and operating systems. It is sometimes used to gather information in support of exploitation, execution or lateral movement.",
+ "description": "Nmap was executed on a Linux host. Nmap is a FOSS tool for network scanning and security testing. It can map and discover networks, and identify listening services and operating systems. It is sometimes used to gather information in support of exploitation, execution or lateral movement.",
"false_positives": [
"Security testing tools and frameworks may run `Nmap` in the course of security auditing. Some normal use of this command may originate from security engineers and network or server administrators. Use of nmap by ordinary users is uncommon."
],
@@ -7,9 +7,8 @@
"auditbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Nmap Process Activity",
- "query": "process.name: nmap",
+ "query": "process.name:nmap",
"references": [
"https://en.wikipedia.org/wiki/Nmap"
],
@@ -22,4 +21,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_nping_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_nping_activity.json
index 6a713d22e321..8e71b5b90671 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_nping_activity.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_nping_activity.json
@@ -1,15 +1,14 @@
{
- "description": "Nping ran on a Linux host. Nping is part of the Nmap tool suite and has the ability to construct raw packets for a wide variety of security testing applications, including denial of service testing.",
+ "description": "Nping ran on a Linux host. Nping is part of the Nmap tool suite and has the ability to construct raw packets for a wide variety of security testing applications, including denial of service testing.",
"false_positives": [
- "Some normal use of this command may originate from security engineers and network or server administrators, but this is usually not routine or unannounced. Use of `Nping` by non-engineers or ordinary users is uncommon."
+ "Some normal use of this command may originate from security engineers and network or server administrators, but this is usually not routine or unannounced. Use of `Nping` by non-engineers or ordinary users is uncommon."
],
"index": [
"auditbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Nping Process Activity",
- "query": "process.name: nping and event.action:executed",
+ "query": "process.name:nping and event.action:executed",
"references": [
"https://en.wikipedia.org/wiki/Nmap"
],
@@ -22,4 +21,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_process_started_in_temp_directory.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_process_started_in_temp_directory.json
index c80bb4eb4161..c50026d7736a 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_process_started_in_temp_directory.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_process_started_in_temp_directory.json
@@ -1,15 +1,14 @@
{
"description": "Identifies processes running in a temporary folder. This is sometimes done by adversaries to hide malware.",
"false_positives": [
- "Build systems, like Jenkins, may start processes in the `/tmp` directory. These can be exempted by name or by username."
+ "Build systems, like Jenkins, may start processes in the `/tmp` directory. These can be exempted by name or by username."
],
"index": [
"auditbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Unusual Process Execution - Temp",
- "query": "process.working_directory: /tmp and event.action:executed",
+ "query": "process.working_directory:/tmp and event.action:executed",
"risk_score": 47,
"rule_id": "df959768-b0c9-4d45-988c-5606a2be8e5a",
"severity": "medium",
@@ -19,4 +18,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_shell_activity_by_web_server.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_shell_activity_by_web_server.json
index d9455ab7d5b3..01f117e0a225 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_shell_activity_by_web_server.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_shell_activity_by_web_server.json
@@ -7,9 +7,8 @@
"auditbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Potential Shell via Web Server",
- "query": "process.name: bash and user.name: (apache or www or \"www-data\") and event.action:executed",
+ "query": "process.name:bash and user.name:(apache or www or www-data) and event.action:executed",
"references": [
"https://pentestlab.blog/tag/web-shell/"
],
@@ -39,4 +38,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_socat_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_socat_activity.json
index 56fb41dc5f78..a16b164e9ee4 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_socat_activity.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_socat_activity.json
@@ -1,15 +1,14 @@
{
"description": "A Socat process is running on a Linux host. Socat is often used as a persistence mechanism by exporting a reverse shell, or by serving a shell on a listening port. Socat is also sometimes used for lateral movement.",
"false_positives": [
- "Socat is a dual-use tool that can be used for benign or malicious activity. Some normal use of this program, at varying levels of frequency, may originate from scripts, automation tools, and frameworks. Usage by web servers is more likely to be suspicious."
+ "Socat is a dual-use tool that can be used for benign or malicious activity. Some normal use of this program, at varying levels of frequency, may originate from scripts, automation tools, and frameworks. Usage by web servers is more likely to be suspicious."
],
"index": [
"auditbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Socat Process Activity",
- "query": "process.name:socat and not process.args:\"-V\" and event.action:executed",
+ "query": "process.name:socat and not process.args:-V and event.action:executed",
"references": [
"https://blog.ropnop.com/upgrading-simple-shells-to-fully-interactive-ttys/#method-2-using-socat"
],
@@ -22,4 +21,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_strace_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_strace_activity.json
index fdf52e7c728c..9b18039b63fd 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_strace_activity.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_strace_activity.json
@@ -7,9 +7,8 @@
"auditbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Strace Process Activity",
- "query": "process.name: strace and event.action:executed",
+ "query": "process.name:strace and event.action:executed",
"references": [
"https://en.wikipedia.org/wiki/Strace"
],
@@ -22,4 +21,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_tcpdump_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_tcpdump_activity.json
index 908e892026ee..5ae48c8db998 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_tcpdump_activity.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_tcpdump_activity.json
@@ -7,9 +7,8 @@
"auditbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Network Sniffing via Tcpdump",
- "query": "process.name: tcpdump and event.action:executed",
+ "query": "process.name:tcpdump and event.action:executed",
"risk_score": 21,
"rule_id": "7a137d76-ce3d-48e2-947d-2747796a78c0",
"severity": "low",
@@ -51,4 +50,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_whoami_commmand.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_whoami_commmand.json
index 052ff34d15dc..7fef4e813da9 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_whoami_commmand.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/linux_whoami_commmand.json
@@ -1,5 +1,5 @@
{
- "description": "The whoami application was executed on a Linux host. This is often used by tools and persistence mechanisms to test for privileged access.",
+ "description": "The whoami application was executed on a Linux host. This is often used by tools and persistence mechanisms to test for privileged access.",
"false_positives": [
"Security testing tools and frameworks may run this command. Some normal use of this command may originate from automation tools and frameworks."
],
@@ -7,9 +7,8 @@
"auditbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "User Discovery via Whoami",
- "query": "process.name: whoami and event.action:executed",
+ "query": "process.name:whoami and event.action:executed",
"risk_score": 21,
"rule_id": "120559c6-5e24-49f4-9e30-8ffe697df6b9",
"severity": "low",
@@ -36,4 +35,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_dns_directly_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_dns_directly_to_the_internet.json
index 56c11c236eec..e08d681d1446 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_dns_directly_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_dns_directly_to_the_internet.json
@@ -1,5 +1,5 @@
{
- "description": "This rule detects when an internal network client sends DNS traffic directly to the Internet.\nThis is atypical behavior for a managed network, and can be indicative of malware,\nexfiltration, command and control, or, simply, misconfiguration. This DNS activity also impacts your\norganization's ability to provide enterprise monitoring and logging of DNS, and opens\nyour network to a variety of abuses and malicious communications.\n",
+ "description": "This rule detects when an internal network client sends DNS traffic directly to the Internet. This is atypical behavior for a managed network, and can be indicative of malware, exfiltration, command and control, or, simply, misconfiguration. This DNS activity also impacts your organization's ability to provide enterprise monitoring and logging of DNS, and opens your network to a variety of abuses and malicious communications.",
"false_positives": [
"Exclude DNS servers from this rule as this is expected behavior. Endpoints usually query local DNS servers defined in their DHCP scopes, but this may be overridden if a user configures their endpoint to use a remote DNS server. This is uncommon in managed enterprise networks because it could break intranet name resolution when split horizon DNS is utilized. Some consumer VPN services and browser plug-ins may send DNS traffic to remote Internet destinations. In that case, such devices or networks can be excluded from this rule when this is expected behavior."
],
@@ -7,9 +7,8 @@
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "DNS Activity to the Internet",
- "query": "destination.port:53 and (\n network.direction: outbound or (\n source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n not destination.ip:( 169.254.169.254/32 or 127.0.0.53/32 or 10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or 224.0.0.251 or ff02\\:\\:fb or 255.255.255.255 )\n )\n)\n",
+ "query": "destination.port:53 and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and not destination.ip:(10.0.0.0/8 or 127.0.0.0/8 or 169.254.169.254/32 or 172.16.0.0/12 or 192.168.0.0/16 or 224.0.0.251 or 224.0.0.252 or 255.255.255.255 or \"::1\" or \"ff02::fb\")",
"references": [
"https://www.us-cert.gov/ncas/alerts/TA15-240A",
"https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-81-2.pdf"
@@ -39,5 +38,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_ftp_file_transfer_protocol_activity_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_ftp_file_transfer_protocol_activity_to_the_internet.json
index a3a692596090..24c3bad81722 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_ftp_file_transfer_protocol_activity_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_ftp_file_transfer_protocol_activity_to_the_internet.json
@@ -1,5 +1,5 @@
{
- "description": "This rule detects events that may indicate the use of FTP network connections to the Internet.\nThe File Transfer Protocol (FTP) has been around in its current form since the\n1980s. It can be a common and efficient procedure on your network to send and\nreceive files. Because of this, adversaries will also often use this protocol\nto exfiltrate data from your network or download new tools. Additionally, FTP\nis a plain-text protocol which, if intercepted, may expose usernames and\npasswords. FTP activity involving servers subject to regulations or compliance\nstandards may be unauthorized.\n",
+ "description": "This rule detects events that may indicate the use of FTP network connections to the Internet. The File Transfer Protocol (FTP) has been around in its current form since the 1980s. It can be a common and efficient procedure on your network to send and receive files. Because of this, adversaries will also often use this protocol to exfiltrate data from your network or download new tools. Additionally, FTP is a plain-text protocol which, if intercepted, may expose usernames and passwords. FTP activity involving servers subject to regulations or compliance standards may be unauthorized.",
"false_positives": [
"FTP servers should be excluded from this rule as this is expected behavior. Some business workflows may use FTP for data exchange. These workflows often have expected characteristics such as users, sources, and destinations. FTP activity involving an unusual source or destination may be more suspicious. FTP activity involving a production server that has no known associated FTP workflow or business requirement is often suspicious."
],
@@ -7,9 +7,8 @@
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "FTP (File Transfer Protocol) Activity to the Internet",
- "query": "network.transport: tcp and destination.port: (20 or 21) and (\n network.direction: outbound or (\n source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n not destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port:(20 or 21) and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and not destination.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\")",
"risk_score": 21,
"rule_id": "87ec6396-9ac4-4706-bcf0-2ebb22002f43",
"severity": "low",
@@ -50,5 +49,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_irc_internet_relay_chat_protocol_activity_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_irc_internet_relay_chat_protocol_activity_to_the_internet.json
index 0b5259d3417f..bf286d4cab50 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_irc_internet_relay_chat_protocol_activity_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_irc_internet_relay_chat_protocol_activity_to_the_internet.json
@@ -1,5 +1,5 @@
{
- "description": "This rule detects events that use common ports for Internet Relay Chat (IRC) to the Internet.\nIRC is a common protocol that can be used for chat and file transfers. This\nprotocol is also a good candidate for remote control of malware and data\ntransfers to and from a network.\n",
+ "description": "This rule detects events that use common ports for Internet Relay Chat (IRC) to the Internet. IRC is a common protocol that can be used for chat and file transfers. This protocol is also a good candidate for remote control of malware and data transfers to and from a network.",
"false_positives": [
"IRC activity may be normal behavior for developers and engineers but is unusual for non-engineering end users. IRC activity involving an unusual source or destination may be more suspicious. IRC activity involving a production server is often suspicious. Because these ports are in the ephemeral range, this rule may false under certain conditions, such as when a NAT-ed web server replies to a client which has used a port in the range by coincidence. In this case, these servers can be excluded. Some legacy applications may use these ports, but this is very uncommon and usually only appears in local traffic using private IPs, which does not match this rule's conditions."
],
@@ -7,9 +7,8 @@
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "IRC (Internet Relay Chat) Protocol Activity to the Internet",
- "query": "network.transport: tcp and destination.port:(6667 or 6697) and (\n network.direction: outbound or (\n source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n not destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port:(6667 or 6697) and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and not destination.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\")",
"risk_score": 47,
"rule_id": "c6474c34-4953-447a-903e-9fcb7b6661aa",
"severity": "medium",
@@ -50,5 +49,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_nat_traversal_port_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_nat_traversal_port_activity.json
index 675fd588a183..61c1e3d47cf7 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_nat_traversal_port_activity.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_nat_traversal_port_activity.json
@@ -1,5 +1,5 @@
{
- "description": "This rule detects events that could be describing IPSEC NAT Traversal traffic.\nIPSEC is a VPN technology that allows one system to talk to another using\nencrypted tunnels. NAT Traversal enables these tunnels to communicate over the\nInternet where one of the sides is behind a NAT router gateway. This may be\ncommon on your network, but this technique is also used by threat actors to\navoid detection.\n",
+ "description": "This rule detects events that could be describing IPSEC NAT Traversal traffic. IPSEC is a VPN technology that allows one system to talk to another using encrypted tunnels. NAT Traversal enables these tunnels to communicate over the Internet where one of the sides is behind a NAT router gateway. This may be common on your network, but this technique is also used by threat actors to avoid detection.",
"false_positives": [
"Some networks may utilize these protocols but usage that is unfamiliar to local network administrators can be unexpected and suspicious. Because this port is in the ephemeral range, this rule may false under certain conditions, such as when an application server with a public IP address replies to a client which has used a UDP port in the range by coincidence. This is uncommon but such servers can be excluded."
],
@@ -7,9 +7,8 @@
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "IPSEC NAT Traversal Port Activity",
- "query": "network.transport: udp and destination.port: 4500",
+ "query": "network.transport:udp and destination.port:4500",
"risk_score": 21,
"rule_id": "a9cb3641-ff4b-4cdc-a063-b4b8d02a67c7",
"severity": "low",
@@ -36,4 +35,4 @@
],
"type": "query",
"version": 2
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_port_26_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_port_26_activity.json
index bc00383f9452..a9a39b61884c 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_port_26_activity.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_port_26_activity.json
@@ -1,5 +1,5 @@
{
- "description": "This rule detects events that may indicate use of SMTP on TCP port 26. This\nport is commonly used by several popular mail transfer agents to deconflict\nwith the default SMTP port 25. This port has also been used by a malware family\ncalled BadPatch for command and control of Windows systems.\n",
+ "description": "This rule detects events that may indicate use of SMTP on TCP port 26. This port is commonly used by several popular mail transfer agents to deconflict with the default SMTP port 25. This port has also been used by a malware family called BadPatch for command and control of Windows systems.",
"false_positives": [
"Servers that process email traffic may cause false positives and should be excluded from this rule as this is expected behavior."
],
@@ -7,9 +7,8 @@
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "SMTP on Port 26/TCP",
- "query": "network.transport: tcp and destination.port: 26\n",
+ "query": "network.transport:tcp and destination.port:26",
"references": [
"https://unit42.paloaltonetworks.com/unit42-badpatch/",
"https://isc.sans.edu/forums/diary/Next+up+whats+up+with+TCP+port+26/25564/"
@@ -55,4 +54,4 @@
],
"type": "query",
"version": 2
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_port_8000_activity_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_port_8000_activity_to_the_internet.json
index f418648bebdb..2f1390411f97 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_port_8000_activity_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_port_8000_activity_to_the_internet.json
@@ -1,5 +1,5 @@
{
- "description": "TCP Port 8000 is commonly used for development environments of web server\nsoftware. It generally should not be exposed directly to the Internet. If you are\nrunning software like this on the Internet, you should consider placing it behind\na reverse proxy.\n",
+ "description": "TCP Port 8000 is commonly used for development environments of web server software. It generally should not be exposed directly to the Internet. If you are running software like this on the Internet, you should consider placing it behind a reverse proxy.",
"false_positives": [
"Because this port is in the ephemeral range, this rule may false under certain conditions, such as when a NATed web server replies to a client which has used a port in the range by coincidence. In this case, such servers can be excluded. Some applications may use this port but this is very uncommon and usually appears in local traffic using private IPs, which this rule does not match. Some cloud environments, particularly development environments, may use this port when VPNs or direct connects are not in use and cloud instances are accessed across the Internet."
],
@@ -7,9 +7,8 @@
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "TCP Port 8000 Activity to the Internet",
- "query": "network.transport: tcp and destination.port: 8000 and (\n network.direction: outbound or (\n source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n not destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port:8000 and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and not destination.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\")",
"risk_score": 21,
"rule_id": "08d5d7e2-740f-44d8-aeda-e41f4263efaf",
"severity": "low",
@@ -35,5 +34,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_pptp_point_to_point_tunneling_protocol_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_pptp_point_to_point_tunneling_protocol_activity.json
index 2321b813a155..f7170d8d33a5 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_pptp_point_to_point_tunneling_protocol_activity.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_pptp_point_to_point_tunneling_protocol_activity.json
@@ -1,5 +1,5 @@
{
- "description": "This rule detects events that may indicate use of a PPTP VPN connection. Some\nthreat actors use these types of connections to tunnel their traffic while\navoiding detection.\n",
+ "description": "This rule detects events that may indicate use of a PPTP VPN connection. Some threat actors use these types of connections to tunnel their traffic while avoiding detection.",
"false_positives": [
"Some networks may utilize PPTP protocols but this is uncommon as more modern VPN technologies are available. Usage that is unfamiliar to local network administrators can be unexpected and suspicious. Torrenting applications may use this port. Because this port is in the ephemeral range, this rule may false under certain conditions, such as when an application server replies to a client that used this port by coincidence. This is uncommon but such servers can be excluded."
],
@@ -7,9 +7,8 @@
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "PPTP (Point to Point Tunneling Protocol) Activity",
- "query": "network.transport: tcp and destination.port: 1723\n",
+ "query": "network.transport:tcp and destination.port:1723",
"risk_score": 21,
"rule_id": "d2053495-8fe7-4168-b3df-dad844046be3",
"severity": "low",
@@ -36,4 +35,4 @@
],
"type": "query",
"version": 2
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_proxy_port_activity_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_proxy_port_activity_to_the_internet.json
index 58bba5b3fa71..da4319cf1530 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_proxy_port_activity_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_proxy_port_activity_to_the_internet.json
@@ -1,15 +1,14 @@
{
- "description": "This rule detects events that may describe network events of proxy use to the\nInternet. It includes popular HTTP proxy ports and SOCKS proxy ports. Typically,\nenvironments will use an internal IP address for a proxy server. It can also\nbe used to circumvent network controls and detection mechanisms.\n",
+ "description": "This rule detects events that may describe network events of proxy use to the Internet. It includes popular HTTP proxy ports and SOCKS proxy ports. Typically, environments will use an internal IP address for a proxy server. It can also be used to circumvent network controls and detection mechanisms.",
"false_positives": [
- "Some proxied applications may use these ports but this usually occurs in local traffic using private IPs\n which this rule does not match. Proxies are widely used as a security technology but in enterprise environments\n this is usually local traffic which this rule does not match. Internet proxy services using these ports can be\n white-listed if desired. Some screen recording applications may use these ports. Proxy port activity involving\n an unusual source or destination may be more suspicious. Some cloud environments may use this port when VPNs or\n direct connects are not in use and cloud instances are accessed across the Internet. Because these ports are in\n the ephemeral range, this rule may false under certain conditions such as when a NATed web server replies to a\n client which has used a port in the range by coincidence. In this case, such servers can be excluded if desired."
+ "Some proxied applications may use these ports but this usually occurs in local traffic using private IPs which this rule does not match. Proxies are widely used as a security technology but in enterprise environments this is usually local traffic which this rule does not match. Internet proxy services using these ports can be white-listed if desired. Some screen recording applications may use these ports. Proxy port activity involving an unusual source or destination may be more suspicious. Some cloud environments may use this port when VPNs or direct connects are not in use and cloud instances are accessed across the Internet. Because these ports are in the ephemeral range, this rule may false under certain conditions such as when a NATed web server replies to a client which has used a port in the range by coincidence. In this case, such servers can be excluded if desired."
],
"index": [
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Proxy Port Activity to the Internet",
- "query": "network.transport: tcp and destination.port: (3128 or 8080 or 1080) and (\n network.direction: outbound or (\n source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n not destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port:(1080 or 3128 or 8080) and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and not destination.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\")",
"risk_score": 47,
"rule_id": "ad0e5e75-dd89-4875-8d0a-dfdc1828b5f3",
"severity": "medium",
@@ -35,5 +34,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rdp_remote_desktop_protocol_from_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rdp_remote_desktop_protocol_from_the_internet.json
index 03e507753cd2..d3b65a36f084 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rdp_remote_desktop_protocol_from_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rdp_remote_desktop_protocol_from_the_internet.json
@@ -1,15 +1,14 @@
{
- "description": "This rule detects network events that may indicate the use of RDP traffic\nfrom the Internet. RDP is commonly used by system administrators to remotely\ncontrol a system for maintenance or to use shared resources. It should almost\nnever be directly exposed to the Internet, as it is frequently targeted and\nexploited by threat actors as an initial access or back-door vector.\n",
+ "description": "This rule detects network events that may indicate the use of RDP traffic from the Internet. RDP is commonly used by system administrators to remotely control a system for maintenance or to use shared resources. It should almost never be directly exposed to the Internet, as it is frequently targeted and exploited by threat actors as an initial access or back-door vector.",
"false_positives": [
- " Some network security policies allow RDP directly from the Internet but usage that is unfamiliar to\n server or network owners can be unexpected and suspicious. RDP services may be exposed directly to the\n Internet in some networks such as cloud environments. In such cases, only RDP gateways, bastions or jump\n servers may be expected expose RDP directly to the Internet and can be exempted from this rule. RDP may\n be required by some work-flows such as remote access and support for specialized software products and\n servers. Such work-flows are usually known and not unexpected."
+ "Some network security policies allow RDP directly from the Internet but usage that is unfamiliar to server or network owners can be unexpected and suspicious. RDP services may be exposed directly to the Internet in some networks such as cloud environments. In such cases, only RDP gateways, bastions or jump servers may be expected expose RDP directly to the Internet and can be exempted from this rule. RDP may be required by some work-flows such as remote access and support for specialized software products and servers. Such work-flows are usually known and not unexpected."
],
"index": [
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "RDP (Remote Desktop Protocol) from the Internet",
- "query": "network.transport: tcp and destination.port: 3389 and (\n network.direction: inbound or (\n not source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n and destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port:3389 and not source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and destination.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\")",
"risk_score": 47,
"rule_id": "8c1bdde8-4204-45c0-9e0c-c85ca3902488",
"severity": "medium",
@@ -65,5 +64,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rdp_remote_desktop_protocol_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rdp_remote_desktop_protocol_to_the_internet.json
index af2279b2d900..79618a867c73 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rdp_remote_desktop_protocol_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rdp_remote_desktop_protocol_to_the_internet.json
@@ -1,15 +1,14 @@
{
- "description": "This rule detects network events that may indicate the use of RDP traffic\nto the Internet. RDP is commonly used by system administrators to remotely\ncontrol a system for maintenance or to use shared resources. It should almost\nnever be directly exposed to the Internet, as it is frequently targeted and\nexploited by threat actors as an initial access or back-door vector.\n",
+ "description": "This rule detects network events that may indicate the use of RDP traffic to the Internet. RDP is commonly used by system administrators to remotely control a system for maintenance or to use shared resources. It should almost never be directly exposed to the Internet, as it is frequently targeted and exploited by threat actors as an initial access or back-door vector.",
"false_positives": [
- "RDP connections may be made directly to Internet destinations in order to access\n Windows cloud server instances but such connections are usually made only by engineers.\n In such cases, only RDP gateways, bastions or jump servers may be expected Internet\n destinations and can be exempted from this rule. RDP may be required by some work-flows\n such as remote access and support for specialized software products and servers. Such\n work-flows are usually known and not unexpected. Usage that is unfamiliar to server or\n network owners can be unexpected and suspicious."
+ "RDP connections may be made directly to Internet destinations in order to access Windows cloud server instances but such connections are usually made only by engineers. In such cases, only RDP gateways, bastions or jump servers may be expected Internet destinations and can be exempted from this rule. RDP may be required by some work-flows such as remote access and support for specialized software products and servers. Such work-flows are usually known and not unexpected. Usage that is unfamiliar to server or network owners can be unexpected and suspicious."
],
"index": [
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "RDP (Remote Desktop Protocol) to the Internet",
- "query": "network.transport: tcp and destination.port: 3389 and (\n network.direction: outbound or (\n source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n not destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port:3389 and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and not destination.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\")",
"risk_score": 21,
"rule_id": "e56993d2-759c-4120-984c-9ec9bb940fd5",
"severity": "low",
@@ -50,5 +49,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rpc_remote_procedure_call_from_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rpc_remote_procedure_call_from_the_internet.json
index 4539d639a593..da1e46750f3b 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rpc_remote_procedure_call_from_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rpc_remote_procedure_call_from_the_internet.json
@@ -1,12 +1,11 @@
{
- "description": "This rule detects network events that may indicate the use of RPC traffic\nfrom the Internet. RPC is commonly used by system administrators to remotely\ncontrol a system for maintenance or to use shared resources. It should almost\nnever be directly exposed to the Internet, as it is frequently targeted and\nexploited by threat actors as an initial access or back-door vector.\n",
+ "description": "This rule detects network events that may indicate the use of RPC traffic from the Internet. RPC is commonly used by system administrators to remotely control a system for maintenance or to use shared resources. It should almost never be directly exposed to the Internet, as it is frequently targeted and exploited by threat actors as an initial access or back-door vector.",
"index": [
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "RPC (Remote Procedure Call) from the Internet",
- "query": "network.transport: tcp and destination.port: 135 and (\n network.direction: inbound or (\n not source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port:135 and not source.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\") and destination.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)",
"risk_score": 73,
"rule_id": "143cb236-0956-4f42-a706-814bcaa0cf5a",
"severity": "high",
@@ -32,5 +31,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rpc_remote_procedure_call_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rpc_remote_procedure_call_to_the_internet.json
index dd1b57572bcb..d07d19b8fffe 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rpc_remote_procedure_call_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_rpc_remote_procedure_call_to_the_internet.json
@@ -1,12 +1,11 @@
{
- "description": "This rule detects network events that may indicate the use of RPC traffic\nto the Internet. RPC is commonly used by system administrators to remotely\ncontrol a system for maintenance or to use shared resources. It should almost\nnever be directly exposed to the Internet, as it is frequently targeted and\nexploited by threat actors as an initial access or back-door vector.\n",
+ "description": "This rule detects network events that may indicate the use of RPC traffic to the Internet. RPC is commonly used by system administrators to remotely control a system for maintenance or to use shared resources. It should almost never be directly exposed to the Internet, as it is frequently targeted and exploited by threat actors as an initial access or back-door vector.",
"index": [
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "RPC (Remote Procedure Call) to the Internet",
- "query": "network.transport: tcp and destination.port: 135 and (\n network.direction: outbound or (\n source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n not destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port:135 and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and not destination.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\")",
"risk_score": 73,
"rule_id": "32923416-763a-4531-bb35-f33b9232ecdb",
"severity": "high",
@@ -32,5 +31,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_smb_windows_file_sharing_activity_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_smb_windows_file_sharing_activity_to_the_internet.json
index 8b97df218299..93a4b0ebbbd8 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_smb_windows_file_sharing_activity_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_smb_windows_file_sharing_activity_to_the_internet.json
@@ -1,12 +1,11 @@
{
- "description": "This rule detects network events that may indicate the use of Windows\nfile sharing (also called SMB or CIFS) traffic to the Internet. SMB is commonly\nused within networks to share files, printers, and other system resources amongst\ntrusted systems. It should almost never be directly exposed to the Internet, as\nit is frequently targeted and exploited by threat actors as an initial access\nor back-door vector or for data exfiltration.\n",
+ "description": "This rule detects network events that may indicate the use of Windows file sharing (also called SMB or CIFS) traffic to the Internet. SMB is commonly used within networks to share files, printers, and other system resources amongst trusted systems. It should almost never be directly exposed to the Internet, as it is frequently targeted and exploited by threat actors as an initial access or back-door vector or for data exfiltration.",
"index": [
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "SMB (Windows File Sharing) Activity to the Internet",
- "query": "network.transport: tcp and destination.port: (139 or 445) and (\n network.direction: outbound or (\n source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n not destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port:(139 or 445) and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and not destination.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\")",
"risk_score": 73,
"rule_id": "c82b2bd8-d701-420c-ba43-f11a155b681a",
"severity": "high",
@@ -47,5 +46,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_smtp_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_smtp_to_the_internet.json
index c6aa5eef372f..ca287605490e 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_smtp_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_smtp_to_the_internet.json
@@ -1,15 +1,14 @@
{
- "description": "This rule detects events that may describe SMTP traffic from internal\nhosts to a host across the Internet. In an enterprise network, there is typically\na dedicated internal host that performs this function. It is also\nfrequently abused by threat actors for command and control, or data exfiltration.\n",
+ "description": "This rule detects events that may describe SMTP traffic from internal hosts to a host across the Internet. In an enterprise network, there is typically a dedicated internal host that performs this function. It is also frequently abused by threat actors for command and control, or data exfiltration.",
"false_positives": [
- "NATed servers that process email traffic may false and should be excluded from this rule as this is expected behavior for them. Consumer and personal devices may send email traffic to remote Internet destinations. In this case, such devices or networks can be excluded from this rule if this is expected behavior."
+ "NATed servers that process email traffic may false and should be excluded from this rule as this is expected behavior for them. Consumer and personal devices may send email traffic to remote Internet destinations. In this case, such devices or networks can be excluded from this rule if this is expected behavior."
],
"index": [
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "SMTP to the Internet",
- "query": "network.transport: tcp and destination.port: (25 or 465 or 587) and (\n network.direction: outbound or (\n source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n not destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port:(25 or 465 or 587) and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and not destination.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\")",
"risk_score": 21,
"rule_id": "67a9beba-830d-4035-bfe8-40b7e28f8ac4",
"severity": "low",
@@ -50,5 +49,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_sql_server_port_activity_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_sql_server_port_activity_to_the_internet.json
index f11d9705bbda..3a5bd5bff98f 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_sql_server_port_activity_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_sql_server_port_activity_to_the_internet.json
@@ -1,15 +1,14 @@
{
- "description": "This rule detects events that may describe database traffic\n(MS SQL, Oracle, MySQL, and Postgresql) across the Internet. Databases\nshould almost never be directly exposed to the Internet, as they are\nfrequently targeted by threat actors to gain initial access to network resources.\n",
+ "description": "This rule detects events that may describe database traffic (MS SQL, Oracle, MySQL, and Postgresql) across the Internet. Databases should almost never be directly exposed to the Internet, as they are frequently targeted by threat actors to gain initial access to network resources.",
"false_positives": [
- "Because these ports are in the ephemeral range, this rule may false under certain conditions\n such as when a NATed web server replies to a client which has used a port in the range by\n coincidence. In this case, such servers can be excluded if desired. Some cloud environments may\n use this port when VPNs or direct connects are not in use and database instances are accessed\n directly across the Internet."
+ "Because these ports are in the ephemeral range, this rule may false under certain conditions such as when a NATed web server replies to a client which has used a port in the range by coincidence. In this case, such servers can be excluded if desired. Some cloud environments may use this port when VPNs or direct connects are not in use and database instances are accessed directly across the Internet."
],
"index": [
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "SQL Traffic to the Internet",
- "query": "network.transport: tcp and destination.port: (1433 or 1521 or 3336 or 5432) and (\n network.direction: outbound or (\n source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n not destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port:(1433 or 1521 or 3336 or 5432) and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and not destination.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\")",
"risk_score": 47,
"rule_id": "139c7458-566a-410c-a5cd-f80238d6a5cd",
"severity": "medium",
@@ -35,5 +34,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_ssh_secure_shell_from_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_ssh_secure_shell_from_the_internet.json
index a95447fc088d..429a91183e88 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_ssh_secure_shell_from_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_ssh_secure_shell_from_the_internet.json
@@ -1,15 +1,14 @@
{
- "description": "This rule detects network events that may indicate the use of SSH traffic\nfrom the Internet. SSH is commonly used by system administrators to remotely\ncontrol a system using the command line shell. If it is exposed to the Internet,\nit should be done with strong security controls as it is frequently targeted and\nexploited by threat actors as an initial access or back-door vector.\n",
+ "description": "This rule detects network events that may indicate the use of SSH traffic from the Internet. SSH is commonly used by system administrators to remotely control a system using the command line shell. If it is exposed to the Internet, it should be done with strong security controls as it is frequently targeted and exploited by threat actors as an initial access or back-door vector.",
"false_positives": [
- "Some network security policies allow SSH directly from the Internet but usage that is\n unfamiliar to server or network owners can be unexpected and suspicious. SSH services may\n be exposed directly to the Internet in some networks such as cloud environments. In such\n cases, only SSH gateways, bastions or jump servers may be expected expose SSH directly to\n the Internet and can be exempted from this rule. SSH may be required by some work-flows\n such as remote access and support for specialized software products and servers. Such\n work-flows are usually known and not unexpected."
+ "Some network security policies allow SSH directly from the Internet but usage that is unfamiliar to server or network owners can be unexpected and suspicious. SSH services may be exposed directly to the Internet in some networks such as cloud environments. In such cases, only SSH gateways, bastions or jump servers may be expected expose SSH directly to the Internet and can be exempted from this rule. SSH may be required by some work-flows such as remote access and support for specialized software products and servers. Such work-flows are usually known and not unexpected."
],
"index": [
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "SSH (Secure Shell) from the Internet",
- "query": "network.transport: tcp and destination.port:22 and (\n network.direction: inbound or (\n not source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port:22 and not source.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\") and destination.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)",
"risk_score": 47,
"rule_id": "ea0784f0-a4d7-4fea-ae86-4baaf27a6f17",
"severity": "medium",
@@ -65,5 +64,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_ssh_secure_shell_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_ssh_secure_shell_to_the_internet.json
index b17d35f96324..a260245b4dad 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_ssh_secure_shell_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_ssh_secure_shell_to_the_internet.json
@@ -1,15 +1,14 @@
{
- "description": "This rule detects network events that may indicate the use of SSH traffic\nfrom the Internet. SSH is commonly used by system administrators to remotely\ncontrol a system using the command line shell. If it is exposed to the Internet,\nit should be done with strong security controls as it is frequently targeted and\nexploited by threat actors as an initial access or back-door vector.\n",
+ "description": "This rule detects network events that may indicate the use of SSH traffic from the Internet. SSH is commonly used by system administrators to remotely control a system using the command line shell. If it is exposed to the Internet, it should be done with strong security controls as it is frequently targeted and exploited by threat actors as an initial access or back-door vector.",
"false_positives": [
- "SSH connections may be made directly to Internet destinations in order to access Linux\n cloud server instances but such connections are usually made only by engineers. In such cases,\n only SSH gateways, bastions or jump servers may be expected Internet destinations and can be\n exempted from this rule. SSH may be required by some work-flows such as remote access and support\n for specialized software products and servers. Such work-flows are usually known and not unexpected.\n Usage that is unfamiliar to server or network owners can be unexpected and suspicious."
+ "SSH connections may be made directly to Internet destinations in order to access Linux cloud server instances but such connections are usually made only by engineers. In such cases, only SSH gateways, bastions or jump servers may be expected Internet destinations and can be exempted from this rule. SSH may be required by some work-flows such as remote access and support for specialized software products and servers. Such work-flows are usually known and not unexpected. Usage that is unfamiliar to server or network owners can be unexpected and suspicious."
],
"index": [
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "SSH (Secure Shell) to the Internet",
- "query": "network.transport: tcp and destination.port:22 and (\n network.direction: outbound or (\n source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n not destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port:22 and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and not destination.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\")",
"risk_score": 21,
"rule_id": "6f1500bc-62d7-4eb9-8601-7485e87da2f4",
"severity": "low",
@@ -35,5 +34,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_telnet_port_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_telnet_port_activity.json
index 99813595013c..4cfe15683c82 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_telnet_port_activity.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_telnet_port_activity.json
@@ -1,15 +1,14 @@
{
- "description": "This rule detects network events that may indicate the use of Telnet traffic.\nTelnet is commonly used by system administrators to remotely control older or embed ed\nsystems using the command line shell. It should almost never be directly exposed to\nthe Internet, as it is frequently targeted and exploited by threat actors as an\ninitial access or back-door vector. As a plain-text protocol, it may also expose\nusernames and passwords to anyone capable of observing the traffic.\n",
+ "description": "This rule detects network events that may indicate the use of Telnet traffic. Telnet is commonly used by system administrators to remotely control older or embed ed systems using the command line shell. It should almost never be directly exposed to the Internet, as it is frequently targeted and exploited by threat actors as an initial access or back-door vector. As a plain-text protocol, it may also expose usernames and passwords to anyone capable of observing the traffic.",
"false_positives": [
- "IoT (Internet of Things) devices and networks may use telnet and can be excluded if\n desired. Some business work-flows may use Telnet for administration of older devices. These\n often have a predictable behavior. Telnet activity involving an unusual source or destination\n may be more suspicious. Telnet activity involving a production server that has no known\n associated Telnet work-flow or business requirement is often suspicious."
+ "IoT (Internet of Things) devices and networks may use telnet and can be excluded if desired. Some business work-flows may use Telnet for administration of older devices. These often have a predictable behavior. Telnet activity involving an unusual source or destination may be more suspicious. Telnet activity involving a production server that has no known associated Telnet work-flow or business requirement is often suspicious."
],
"index": [
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Telnet Port Activity",
- "query": "network.transport: tcp and destination.port: 23",
+ "query": "network.transport:tcp and destination.port:23",
"risk_score": 47,
"rule_id": "34fde489-94b0-4500-a76f-b8a157cf9269",
"severity": "medium",
@@ -66,4 +65,4 @@
],
"type": "query",
"version": 2
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_tor_activity_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_tor_activity_to_the_internet.json
index 47960f879dfb..8c8bb809c9fe 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_tor_activity_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_tor_activity_to_the_internet.json
@@ -1,15 +1,14 @@
{
- "description": "This rule detects network events that may indicate the use of Tor traffic\nto the Internet. Tor is a network protocol that sends traffic through a\nseries of encrypted tunnels used to conceal a user's location and usage.\nTor may be used by threat actors as an alternate communication pathway to\nconceal the actor's identity and avoid detection.\n",
+ "description": "This rule detects network events that may indicate the use of Tor traffic to the Internet. Tor is a network protocol that sends traffic through a series of encrypted tunnels used to conceal a user's location and usage. Tor may be used by threat actors as an alternate communication pathway to conceal the actor's identity and avoid detection.",
"false_positives": [
- "Tor client activity is uncommon in managed enterprise networks but may be common\n in unmanaged or public networks where few security policies apply. Because these ports\n are in the ephemeral range, this rule may false under certain conditions such as when a\n NATed web server replies to a client which has used one of these ports by coincidence.\n In this case, such servers can be excluded if desired."
+ "Tor client activity is uncommon in managed enterprise networks but may be common in unmanaged or public networks where few security policies apply. Because these ports are in the ephemeral range, this rule may false under certain conditions such as when a NATed web server replies to a client which has used one of these ports by coincidence. In this case, such servers can be excluded if desired."
],
"index": [
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Tor Activity to the Internet",
- "query": "network.transport: tcp and destination.port: (9001 or 9030) and (\n network.direction: outbound or (\n source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n not destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port:(9001 or 9030) and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and not destination.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\")",
"risk_score": 47,
"rule_id": "7d2c38d7-ede7-4bdf-b140-445906e6c540",
"severity": "medium",
@@ -50,5 +49,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_vnc_virtual_network_computing_from_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_vnc_virtual_network_computing_from_the_internet.json
index d9195a2d2e98..4204a4fe62e8 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_vnc_virtual_network_computing_from_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_vnc_virtual_network_computing_from_the_internet.json
@@ -1,15 +1,14 @@
{
- "description": "This rule detects network events that may indicate the use of VNC traffic\nfrom the Internet. VNC is commonly used by system administrators to remotely\ncontrol a system for maintenance or to use shared resources. It should almost\nnever be directly exposed to the Internet, as it is frequently targeted and\nexploited by threat actors as an initial access or back-door vector.\n",
+ "description": "This rule detects network events that may indicate the use of VNC traffic from the Internet. VNC is commonly used by system administrators to remotely control a system for maintenance or to use shared resources. It should almost never be directly exposed to the Internet, as it is frequently targeted and exploited by threat actors as an initial access or back-door vector.",
"false_positives": [
- "VNC connections may be received directly to Linux cloud server instances but\n such connections are usually made only by engineers. VNC is less common than SSH\n or RDP but may be required by some work-flows such as remote access and support\n for specialized software products or servers. Such work-flows are usually known\n and not unexpected. Usage that is unfamiliar to server or network owners can be\n unexpected and suspicious."
+ "VNC connections may be received directly to Linux cloud server instances but such connections are usually made only by engineers. VNC is less common than SSH or RDP but may be required by some work-flows such as remote access and support for specialized software products or servers. Such work-flows are usually known and not unexpected. Usage that is unfamiliar to server or network owners can be unexpected and suspicious."
],
"index": [
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "VNC (Virtual Network Computing) from the Internet",
- "query": "network.transport: tcp and (destination.port >= 5800 and destination.port <= 5810) and (\n network.direction: inbound or (\n not source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port >= 5800 and destination.port <= 5810 and not source.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\") and destination.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)",
"risk_score": 73,
"rule_id": "5700cb81-df44-46aa-a5d7-337798f53eb8",
"severity": "high",
@@ -50,5 +49,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_vnc_virtual_network_computing_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_vnc_virtual_network_computing_to_the_internet.json
index 57131e28ee9a..898282e36df1 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_vnc_virtual_network_computing_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/network_vnc_virtual_network_computing_to_the_internet.json
@@ -1,15 +1,14 @@
{
- "description": "This rule detects network events that may indicate the use of VNC traffic\nto the Internet. VNC is commonly used by system administrators to remotely\ncontrol a system for maintenance or to use shared resources. It should almost\nnever be directly exposed to the Internet, as it is frequently targeted and\nexploited by threat actors as an initial access or back-door vector.",
+ "description": "This rule detects network events that may indicate the use of VNC traffic to the Internet. VNC is commonly used by system administrators to remotely control a system for maintenance or to use shared resources. It should almost never be directly exposed to the Internet, as it is frequently targeted and exploited by threat actors as an initial access or back-door vector.",
"false_positives": [
- "VNC connections may be made directly to Linux cloud server instances but such\n connections are usually made only by engineers. VNC is less common than SSH or RDP\n but may be required by some work flows such as remote access and support for\n specialized software products or servers. Such work-flows are usually known and not\n unexpected. Usage that is unfamiliar to server or network owners can be unexpected\n and suspicious."
+ "VNC connections may be made directly to Linux cloud server instances but such connections are usually made only by engineers. VNC is less common than SSH or RDP but may be required by some work flows such as remote access and support for specialized software products or servers. Such work-flows are usually known and not unexpected. Usage that is unfamiliar to server or network owners can be unexpected and suspicious."
],
"index": [
"filebeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "VNC (Virtual Network Computing) to the Internet",
- "query": "network.transport: tcp and (destination.port >= 5800 and destination.port <= 5810) and (\n network.direction: outbound or (\n source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and\n not destination.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)\n )\n)\n",
+ "query": "network.transport:tcp and destination.port >= 5800 and destination.port <= 5810 and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and not destination.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or \"::1\")",
"risk_score": 47,
"rule_id": "3ad49c61-7adc-42c1-b788-732eda2f5abf",
"severity": "medium",
@@ -35,5 +34,5 @@
}
],
"type": "query",
- "version": 2
-}
+ "version": 3
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/null_user_agent.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/null_user_agent.json
index c08d910a3b35..afbbb2a34d54 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/null_user_agent.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/null_user_agent.json
@@ -25,9 +25,8 @@
"apm-*-transaction*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Web Application Suspicious Activity: No User Agent",
- "query": "url.path: *",
+ "query": "url.path:*",
"references": [
"https://en.wikipedia.org/wiki/User_agent"
],
@@ -35,9 +34,9 @@
"rule_id": "43303fd4-4839-4e48-b2b2-803ab060758d",
"severity": "medium",
"tags": [
- "Elastic",
- "APM"
+ "APM",
+ "Elastic"
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/packetbeat_dns_tunneling.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/packetbeat_dns_tunneling.json
new file mode 100644
index 000000000000..c70725dcb645
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/packetbeat_dns_tunneling.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "A machine learning job detected unusually large numbers of DNS queries for a single top-level DNS domain, which is often used for DNS tunneling. DNS tunneling can be used for command-and-control, persistence, or data exfiltration activity. For example, dnscat tends to generate many DNS questions for a top-level domain as it uses the DNS protocol to tunnel data.",
+ "false_positives": [
+ "DNS domains that use large numbers of child domains, such as software or content distribution networks, can trigger this signal and such parent domains can be excluded."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "packetbeat_dns_tunneling",
+ "name": "DNS Tunneling",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "91f02f01-969f-4167-8f66-07827ac3bdd9",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "ML",
+ "Packetbeat"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/packetbeat_rare_dns_question.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/packetbeat_rare_dns_question.json
new file mode 100644
index 000000000000..3ed40ddf2786
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/packetbeat_rare_dns_question.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "A machine learning job detected a rare and unusual DNS query that indicate network activity with unusual DNS domains. This can be due to initial access, persistence, command-and-control, or exfiltration activity. For example, when a user clicks on a link in a phishing email or opens a malicious document, a request may be sent to download and run a payload from an uncommon domain. When malware is already running, it may send requests to an uncommon DNS domain the malware uses for command-and-control communication.",
+ "false_positives": [
+ "A newly installed program or one that runs rarely as part of a monthly or quarterly workflow could trigger this signal. Network activity that occurs rarely, in small quantities, can trigger this signal. Possible examples are browsing technical support or vendor networks sparsely. A user who visits a new or unique web destination may trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "packetbeat_rare_dns_question",
+ "name": "Unusual DNS Activity",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "746edc4c-c54c-49c6-97a1-651223819448",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "ML",
+ "Packetbeat"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/packetbeat_rare_server_domain.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/packetbeat_rare_server_domain.json
new file mode 100644
index 000000000000..c49bc95be75d
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/packetbeat_rare_server_domain.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "A machine learning job detected an unusual network destination domain name. This can be due to initial access, persistence, command-and-control, or exfiltration activity. For example, when a user clicks on a link in a phishing email or opens a malicious document, a request may be sent to download and run a payload from an uncommon web server name. When malware is already running, it may send requests to an uncommon DNS domain the malware uses for command-and-control communication.",
+ "false_positives": [
+ "Web activity that occurs rarely in small quantities can trigger this signal. Possible examples are browsing technical support or vendor URLs that are used very sparsely. A user who visits a new and unique web destination may trigger this signal when the activity is sparse. Web applications that generate URLs unique to a transaction may trigger this when they are used sparsely. Web domains can be excluded in cases such as these."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "packetbeat_rare_server_domain",
+ "name": "Unusual Network Destination Domain Name",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "17e68559-b274-4948-ad0b-f8415bb31126",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "ML",
+ "Packetbeat"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/packetbeat_rare_urls.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/packetbeat_rare_urls.json
new file mode 100644
index 000000000000..02a4a5f729a1
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/packetbeat_rare_urls.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "A machine learning job detected a rare and unusual URL that indicates unusual web browsing activity. This can be due to initial access, persistence, command-and-control, or exfiltration activity. For example, in a strategic web compromise or watering hole attack, when a trusted website is compromised to target a particular sector or organization, targeted users may receive emails with uncommon URLs for trusted websites. These URLs can be used to download and run a payload. When malware is already running, it may send requests to uncommon URLs on trusted websites the malware uses for command-and-control communication. When rare URLs are observed being requested for a local web server by a remote source, these can be due to web scanning, enumeration or attack traffic, or they can be due to bots and web scrapers which are part of common Internet background traffic.",
+ "false_positives": [
+ "Web activity that occurs rarely in small quantities can trigger this signal. Possible examples are browsing technical support or vendor URLs that are used very sparsely. A user who visits a new and unique web destination may trigger this signal when the activity is sparse. Web applications that generate URLs unique to a transaction may trigger this when they are used sparsely. Web domains can be excluded in cases such as these."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "packetbeat_rare_urls",
+ "name": "Unusual Web Request",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "91f02f01-969f-4167-8f55-07827ac3acc9",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "ML",
+ "Packetbeat"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/packetbeat_rare_user_agent.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/packetbeat_rare_user_agent.json
new file mode 100644
index 000000000000..76ed6b263a70
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/packetbeat_rare_user_agent.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "A machine learning job detected a rare and unusual user agent indicating web browsing activity by an unusual process other than a web browser. This can be due to persistence, command-and-control, or exfiltration activity. Uncommon user agents coming from remote sources to local destinations are often the result of scanners, bots, and web scrapers, which are part of common Internet background traffic. Much of this is noise, but more targeted attacks on websites using tools like Burp or SQLmap can sometimes be discovered by spotting uncommon user agents. Uncommon user agents in traffic from local sources to remote destinations can be any number of things, including harmless programs like weather monitoring or stock-trading programs. However, uncommon user agents from local sources can also be due to malware or scanning activity.",
+ "false_positives": [
+ "Web activity that is uncommon, like security scans, may trigger this signal and may need to be excluded. A new or rarely used program that calls web services may trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "packetbeat_rare_user_agent",
+ "name": "Unusual Web User Agent",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "91f02f01-969f-4167-8d77-07827ac4cee0",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "ML",
+ "Packetbeat"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/rare_process_by_host_linux.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/rare_process_by_host_linux.json
new file mode 100644
index 000000000000..048f93e17065
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/rare_process_by_host_linux.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "Identifies rare processes that do not usually run on individual hosts, which can indicate execution of unauthorized services, malware, or persistence mechanisms. Processes are considered rare when they only run occasionally as compared with other processes running on the host.",
+ "false_positives": [
+ "A newly installed program or one that runs rarely as part of a monthly or quarterly workflow could trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "rare_process_by_host_linux_ecs",
+ "name": "Unusual Process For a Linux Host",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "46f804f5-b289-43d6-a881-9387cf594f75",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Linux",
+ "ML"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/rare_process_by_host_windows.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/rare_process_by_host_windows.json
new file mode 100644
index 000000000000..7bc46cdc04dd
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/rare_process_by_host_windows.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "Identifies rare processes that do not usually run on individual hosts, which can indicate execution of unauthorized services, malware, or persistence mechanisms. Processes are considered rare when they only run occasionally as compared with other processes running on the host.",
+ "false_positives": [
+ "A newly installed program or one that runs rarely as part of a monthly or quarterly workflow could trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "rare_process_by_host_windows_ecs",
+ "name": "Unusual Process For a Windows Host",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "6d448b96-c922-4adb-b51c-b767f1ea5b76",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "ML",
+ "Windows"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/sqlmap_user_agent.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/sqlmap_user_agent.json
index 5c03c3a76e4a..fd240262d021 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/sqlmap_user_agent.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/sqlmap_user_agent.json
@@ -7,7 +7,6 @@
"apm-*-transaction*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Web Application Suspicious Activity: sqlmap User Agent",
"query": "user_agent.original:\"sqlmap/1.3.11#stable (http://sqlmap.org)\"",
"references": [
@@ -17,9 +16,9 @@
"rule_id": "d49cc73f-7a16-4def-89ce-9fc7127d7820",
"severity": "medium",
"tags": [
- "Elastic",
- "APM"
+ "APM",
+ "Elastic"
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/suspicious_login_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/suspicious_login_activity.json
new file mode 100644
index 000000000000..915bc1bcfc05
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/suspicious_login_activity.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "Identifies an unusually high number of authentication attempts.",
+ "false_positives": [
+ "Security audits may trigger this signal. Conditions that generate bursts of failed logins, such as misconfigured applications or account lockouts could trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "suspicious_login_activity_ecs",
+ "name": "Unusual Login Activity",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "4330272b-9724-4bc6-a3ca-f1532b81e5c2",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Linux",
+ "ML"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_network_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_network_activity.json
new file mode 100644
index 000000000000..72671760c9c8
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_network_activity.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "Identifies Windows processes that do not usually use the network but have unexpected network activity, which can indicate command-and-control, lateral movement, persistence, or data exfiltration activity. A process with unusual network activity can denote process exploitation or injection, where the process is used to run persistence mechanisms that allow a malicious actor remote access or control of the host, data exfiltration, and execution of unauthorized network applications.",
+ "false_positives": [
+ "A newly installed program or one that rarely uses the network could trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "windows_anomalous_network_activity_ecs",
+ "name": "Unusual Windows Network Activity",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "ba342eb2-583c-439f-b04d-1fdd7c1417cc",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "ML",
+ "Windows"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_path_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_path_activity.json
new file mode 100644
index 000000000000..082fce438ca9
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_path_activity.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "Identifies processes started from atypical folders in the file system, which might indicate malware execution or persistence mechanisms. In corporate Windows environments, software installation is centrally managed and it is unusual for programs to be executed from user or temporary directories. Processes executed from these locations can denote that a user downloaded software directly from the Internet or a malicious script or macro executed malware.",
+ "false_positives": [
+ "A new and unusual program or artifact download in the course of software upgrades, debugging, or troubleshooting could trigger this signal. Users downloading and running programs from unusual locations, such as temporary directories, browser caches, or profile paths could trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "windows_anomalous_path_activity_ecs",
+ "name": "Unusual Windows Path Activity",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "445a342e-03fb-42d0-8656-0367eb2dead5",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "ML",
+ "Windows"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_process_all_hosts.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_process_all_hosts.json
new file mode 100644
index 000000000000..93469b5a0622
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_process_all_hosts.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "Searches for rare processes running on multiple hosts in an entire fleet or network. This reduces the detection of false positives since automated maintenance processes usually only run occasionally on a single machine but are common to all or many hosts in a fleet.",
+ "false_positives": [
+ "A newly installed program or one that runs rarely as part of a monthly or quarterly workflow could trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "windows_anomalous_process_all_hosts_ecs",
+ "name": "Anomalous Process For a Windows Population",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "6e40d56f-5c0e-4ac6-aece-bee96645b172",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "ML",
+ "Windows"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_process_creation.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_process_creation.json
new file mode 100644
index 000000000000..1b80e443baae
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_process_creation.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "Identifies unusual parent-child process relationships that can indicate malware execution or persistence mechanisms. Malicious scripts often call on other applications and processes as part of their exploit payload. For example, when a malicious Office document runs scripts as part of an exploit payload, Excel or Word may start a script interpreter process, which, in turn, runs a script that downloads and executes malware. Another common scenario is Outlook running an unusual process when malware is downloaded in an email. Monitoring and identifying anomalous process relationships is a method of detecting new and emerging malware that is not yet recognized by anti-virus scanners.",
+ "false_positives": [
+ "Users running scripts in the course of technical support operations of software upgrades could trigger this signal. A newly installed program or one that runs rarely as part of a monthly or quarterly workflow could trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "windows_anomalous_process_creation",
+ "name": "Anomalous Windows Process Creation",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "0b29cab4-dbbd-4a3f-9e8e-1287c7c11ae5",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "ML",
+ "Windows"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_script.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_script.json
new file mode 100644
index 000000000000..4de5443bcaf3
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_script.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "A machine learning job detected a PowerShell script with unusual data characteristics, such as obfuscation, that may be a characteristic of malicious PowerShell script text blocks.",
+ "false_positives": [
+ "Certain kinds of security testing may trigger this signal. PowerShell scripts that use high levels of obfuscation or have unusual script block payloads may trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "windows_anomalous_script",
+ "name": "Suspicious Powershell Script",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "1781d055-5c66-4adf-9d60-fc0fa58337b6",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "ML",
+ "Windows"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_service.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_service.json
new file mode 100644
index 000000000000..7e0641fee68c
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_service.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "A machine learning job detected an unusual Windows service, This can indicate execution of unauthorized services, malware, or persistence mechanisms. In corporate Windows environments, hosts do not generally run many rare or unique services. This job helps detect malware and persistence mechanisms that have been installed and run as a service.",
+ "false_positives": [
+ "A newly installed program or one that runs rarely as part of a monthly or quarterly workflow could trigger this signal."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "windows_anomalous_service",
+ "name": "Unusual Windows Service",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "1781d055-5c66-4adf-9c71-fc0fa58338c7",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "ML",
+ "Windows"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_user_name.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_user_name.json
new file mode 100644
index 000000000000..217404b6eb47
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_anomalous_user_name.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "A machine learning job detected activity for a username that is not normally active, which can indicate unauthorized changes, activity by unauthorized users, lateral movement, or compromised credentials. In many organizations, new usernames are not often created apart from specific types of system activities, such as creating new accounts for new employees. These user accounts quickly become active and routine. Events from rarely used usernames can point to suspicious activity. Additionally, automated Linux fleets tend to see activity from rarely used usernames only when personnel log in to make authorized or unauthorized changes, or threat actors have acquired credentials and log in for malicious purposes. Unusual usernames can also indicate pivoting, where compromised credentials are used to try and move laterally from one host to another.",
+ "false_positives": [
+ "Uncommon user activity can be due to an administrator or help desk technician logging onto a workstation or server in order to perform manual troubleshooting or reconfiguration."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "windows_anomalous_user_name_ecs",
+ "name": "Unusual Windows Username",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "1781d055-5c66-4adf-9c59-fc0fa58336a5",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "ML",
+ "Windows"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_certutil_network_connection.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_certutil_network_connection.json
new file mode 100644
index 000000000000..2cda21cf7d5e
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_certutil_network_connection.json
@@ -0,0 +1,36 @@
+{
+ "description": "Identifies certutil.exe making a network connection. Adversaries could abuse certutil.exe to download a certificate, or malware, from a remote URL.",
+ "index": [
+ "winlogbeat-*"
+ ],
+ "language": "kuery",
+ "max_signals": 33,
+ "name": "Network Connection via Certutil",
+ "query": "process.name:certutil.exe and event.action:\"Network connection detected (rule: NetworkConnect)\" and not destination.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)",
+ "risk_score": 21,
+ "rule_id": "3838e0e3-1850-4850-a411-2e8c5ba40ba8",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Windows"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0011",
+ "name": "Command and Control",
+ "reference": "https://attack.mitre.org/tactics/TA0011/"
+ },
+ "technique": [
+ {
+ "id": "T1105",
+ "name": "Remote File Copy",
+ "reference": "https://attack.mitre.org/techniques/T1105/"
+ }
+ ]
+ }
+ ],
+ "type": "query",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_command_prompt_connecting_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_command_prompt_connecting_to_the_internet.json
index 7ab8034ef408..2427ab4d7cc5 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_command_prompt_connecting_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_command_prompt_connecting_to_the_internet.json
@@ -7,9 +7,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Command Prompt Network Connection",
- "query": "process.name:cmd.exe and event.action:\"Network connection detected (rule: NetworkConnect)\" and not destination.ip:10.0.0.0/8 and not destination.ip:172.16.0.0/12 and not destination.ip:192.168.0.0/16",
+ "query": "process.name:cmd.exe and event.action:\"Network connection detected (rule: NetworkConnect)\" and not destination.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)",
"risk_score": 21,
"rule_id": "89f9a4b0-9f8f-4ee0-8823-c4751a6d6696",
"severity": "low",
@@ -51,4 +50,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_command_shell_started_by_powershell.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_command_shell_started_by_powershell.json
index d914fd2e91a0..f8e5bd22576a 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_command_shell_started_by_powershell.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_command_shell_started_by_powershell.json
@@ -4,7 +4,6 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "PowerShell spawning Cmd",
"query": "process.parent.name:powershell.exe and process.name:cmd.exe",
"risk_score": 21,
@@ -48,4 +47,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_command_shell_started_by_svchost.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_command_shell_started_by_svchost.json
index b7f0c54fedf6..71aafa9984ec 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_command_shell_started_by_svchost.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_command_shell_started_by_svchost.json
@@ -4,7 +4,6 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Svchost spawning Cmd",
"query": "process.parent.name:svchost.exe and process.name:cmd.exe",
"risk_score": 21,
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_credential_dumping_msbuild.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_credential_dumping_msbuild.json
new file mode 100644
index 000000000000..4ff789143855
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_credential_dumping_msbuild.json
@@ -0,0 +1,38 @@
+{
+ "description": "An instance of MSBuild, the Microsoft Build Engine, loaded DLLs (dynamically linked libraries) responsible for Windows credential management. This technique is sometimes used for credential dumping.",
+ "false_positives": [
+ "The Build Engine is commonly used by Windows developers but use by non-engineers is unusual."
+ ],
+ "index": [
+ "winlogbeat-*"
+ ],
+ "language": "kuery",
+ "name": "Microsoft Build Engine Loading Windows Credential Libraries",
+ "query": "(winlog.event_data.OriginalFileName: (vaultcli.dll or SAMLib.DLL) or dll.name: (vaultcli.dll or SAMLib.DLL)) and process.name: MSBuild.exe and event.action: \"Image loaded (rule: ImageLoad)\"",
+ "risk_score": 73,
+ "rule_id": "9d110cb3-5f4b-4c9a-b9f5-53f0a1707ae5",
+ "severity": "high",
+ "tags": [
+ "Elastic",
+ "Windows"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0006",
+ "name": "Credential Access",
+ "reference": "https://attack.mitre.org/tactics/TA0006/"
+ },
+ "technique": [
+ {
+ "id": "T1003",
+ "name": "Credential Dumping",
+ "reference": "https://attack.mitre.org/techniques/T1003/"
+ }
+ ]
+ }
+ ],
+ "type": "query",
+ "version": 1
+}
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_cve_2020_0601.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_cve_2020_0601.json
new file mode 100644
index 000000000000..c08bb7b3315f
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_cve_2020_0601.json
@@ -0,0 +1,36 @@
+{
+ "description": "A spoofing vulnerability exists in the way Windows CryptoAPI (Crypt32.dll) validates Elliptic Curve Cryptography (ECC) certificates. An attacker could exploit the vulnerability by using a spoofed code-signing certificate to sign a malicious executable, making it appear the file was from a trusted, legitimate source.",
+ "index": [
+ "winlogbeat-*"
+ ],
+ "language": "kuery",
+ "max_signals": 33,
+ "name": "Windows CryptoAPI Spoofing Vulnerability (CVE-2020-0601 - CurveBall)",
+ "query": "event.provider:\"Microsoft-Windows-Audit-CVE\" and message:\"[CVE-2020-0601]\"",
+ "risk_score": 21,
+ "rule_id": "56557cde-d923-4b88-adee-c61b3f3b5dc3",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Windows"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0005",
+ "name": "Defense Evasion",
+ "reference": "https://attack.mitre.org/tactics/TA0005/"
+ },
+ "technique": [
+ {
+ "id": "T1116",
+ "name": "Code Signing",
+ "reference": "https://attack.mitre.org/techniques/T1116/"
+ }
+ ]
+ }
+ ],
+ "type": "query",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_defense_evasion_via_filter_manager.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_defense_evasion_via_filter_manager.json
index 86242fd1081a..3f97f7aca74f 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_defense_evasion_via_filter_manager.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_defense_evasion_via_filter_manager.json
@@ -4,7 +4,6 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Potential Evasion via Filter Manager",
"query": "event.code:1 and process.name:fltMC.exe",
"risk_score": 21,
@@ -33,4 +32,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_msbuild_started_by_office_app.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_msbuild_started_by_office_app.json
new file mode 100644
index 000000000000..72e02f8718d0
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_msbuild_started_by_office_app.json
@@ -0,0 +1,56 @@
+{
+ "description": "An instance of MSBuild, the Microsoft Build Engine, was started by Excel or Word. This is unusual behavior for the Build Engine and could have been caused by an Excel or Word document executing a malicious script payload.",
+ "false_positives": [
+ "The Build Engine is commonly used by Windows developers but use by non-engineers is unusual. It is quite unusual for this program to be started by an Office application like Word or Excel."
+ ],
+ "index": [
+ "winlogbeat-*"
+ ],
+ "language": "kuery",
+ "name": "Microsoft Build Engine Started by an Office Application",
+ "query": "process.name:MSBuild.exe and process.parent.name:(eqnedt32.exe or excel.exe or fltldr.exe or msaccess.exe or mspub.exe or outlook.exe or powerpnt.exe or winword.exe) and event.action: \"Process Create (rule: ProcessCreate)\"",
+ "references": [
+ "https://blog.talosintelligence.com/2020/02/building-bypass-with-msbuild.html"
+ ],
+ "risk_score": 73,
+ "rule_id": "c5dc3223-13a2-44a2-946c-e9dc0aa0449c",
+ "severity": "high",
+ "tags": [
+ "Elastic",
+ "Windows"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0005",
+ "name": "Defense Evasion",
+ "reference": "https://attack.mitre.org/tactics/TA0005/"
+ },
+ "technique": [
+ {
+ "id": "T1127",
+ "name": "Trusted Developer Utilities",
+ "reference": "https://attack.mitre.org/techniques/T1127/"
+ }
+ ]
+ },
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0002",
+ "name": "Execution",
+ "reference": "https://attack.mitre.org/tactics/TA0002/"
+ },
+ "technique": [
+ {
+ "id": "T1127",
+ "name": "Trusted Developer Utilities",
+ "reference": "https://attack.mitre.org/techniques/T1127/"
+ }
+ ]
+ }
+ ],
+ "type": "query",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_msbuild_started_by_script.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_msbuild_started_by_script.json
new file mode 100644
index 000000000000..ad519f1516aa
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_msbuild_started_by_script.json
@@ -0,0 +1,53 @@
+{
+ "description": "An instance of MSBuild, the Microsoft Build Engine, was started by a script or the Windows command interpreter. This behavior is unusual and is sometimes used by malicious payloads.",
+ "false_positives": [
+ "The Build Engine is commonly used by Windows developers but use by non-engineers is unusual."
+ ],
+ "index": [
+ "winlogbeat-*"
+ ],
+ "language": "kuery",
+ "name": "Microsoft Build Engine Started by a Script Process",
+ "query": "process.name:MSBuild.exe and process.parent.name:(cmd.exe or powershell.exe or cscript.exe or wscript.exe) and event.action:\"Process Create (rule: ProcessCreate)\"",
+ "risk_score": 21,
+ "rule_id": "9d110cb3-5f4b-4c9a-b9f5-53f0a1707ae2",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Windows"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0005",
+ "name": "Defense Evasion",
+ "reference": "https://attack.mitre.org/tactics/TA0005/"
+ },
+ "technique": [
+ {
+ "id": "T1127",
+ "name": "Trusted Developer Utilities",
+ "reference": "https://attack.mitre.org/techniques/T1127/"
+ }
+ ]
+ },
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0002",
+ "name": "Execution",
+ "reference": "https://attack.mitre.org/tactics/TA0002/"
+ },
+ "technique": [
+ {
+ "id": "T1127",
+ "name": "Trusted Developer Utilities",
+ "reference": "https://attack.mitre.org/techniques/T1127/"
+ }
+ ]
+ }
+ ],
+ "type": "query",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_msbuild_started_by_system_process.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_msbuild_started_by_system_process.json
new file mode 100644
index 000000000000..1bbce904f251
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_msbuild_started_by_system_process.json
@@ -0,0 +1,53 @@
+{
+ "description": "An instance of MSBuild, the Microsoft Build Engine, was started by Explorer or the WMI (Windows Management Instrumentation) subsystem. This behavior is unusual and is sometimes used by malicious payloads.",
+ "false_positives": [
+ "The Build Engine is commonly used by Windows developers but use by non-engineers is unusual."
+ ],
+ "index": [
+ "winlogbeat-*"
+ ],
+ "language": "kuery",
+ "name": "Microsoft Build Engine Started by a System Process",
+ "query": "process.name:MSBuild.exe and process.parent.name:(explorer.exe or wmiprvse.exe) and event.action:\"Process Create (rule: ProcessCreate)\"",
+ "risk_score": 47,
+ "rule_id": "9d110cb3-5f4b-4c9a-b9f5-53f0a1707ae3",
+ "severity": "medium",
+ "tags": [
+ "Elastic",
+ "Windows"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0005",
+ "name": "Defense Evasion",
+ "reference": "https://attack.mitre.org/tactics/TA0005/"
+ },
+ "technique": [
+ {
+ "id": "T1127",
+ "name": "Trusted Developer Utilities",
+ "reference": "https://attack.mitre.org/techniques/T1127/"
+ }
+ ]
+ },
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0002",
+ "name": "Execution",
+ "reference": "https://attack.mitre.org/tactics/TA0002/"
+ },
+ "technique": [
+ {
+ "id": "T1127",
+ "name": "Trusted Developer Utilities",
+ "reference": "https://attack.mitre.org/techniques/T1127/"
+ }
+ ]
+ }
+ ],
+ "type": "query",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_msbuild_started_renamed.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_msbuild_started_renamed.json
new file mode 100644
index 000000000000..eea4b3b4efe1
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_msbuild_started_renamed.json
@@ -0,0 +1,38 @@
+{
+ "description": "An instance of MSBuild, the Microsoft Build Engine, was started after being renamed. This is uncommon behavior and may indicate an attempt to run unnoticed or undetected.",
+ "false_positives": [
+ "The Build Engine is commonly used by Windows developers but use by non-engineers is unusual."
+ ],
+ "index": [
+ "winlogbeat-*"
+ ],
+ "language": "kuery",
+ "name": "Microsoft Build Engine Using an Alternate Name",
+ "query": "(pe.original_file_name:MSBuild.exe or winlog.event_data.OriginalFileName: MSBuild.exe) and not process.name: MSBuild.exe and event.action: \"Process Create (rule: ProcessCreate)\"",
+ "risk_score": 21,
+ "rule_id": "9d110cb3-5f4b-4c9a-b9f5-53f0a1707ae4",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Windows"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0005",
+ "name": "Defense Evasion",
+ "reference": "https://attack.mitre.org/tactics/TA0005/"
+ },
+ "technique": [
+ {
+ "id": "T1036",
+ "name": "Masquerading",
+ "reference": "https://attack.mitre.org/techniques/T1036/"
+ }
+ ]
+ }
+ ],
+ "type": "query",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_msbuild_started_unusal_process.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_msbuild_started_unusal_process.json
new file mode 100644
index 000000000000..81ea14e26538
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_msbuild_started_unusal_process.json
@@ -0,0 +1,41 @@
+{
+ "description": "An instance of MSBuild, the Microsoft Build Engine, started a PowerShell script or the Visual C# Command Line Compiler. This technique is sometimes used to deploy a malicious payload using the Build Engine.",
+ "false_positives": [
+ "The Build Engine is commonly used by Windows developers but use by non-engineers is unusual. If a build system triggers this rule it can be exempted by process, user or host name."
+ ],
+ "index": [
+ "winlogbeat-*"
+ ],
+ "language": "kuery",
+ "name": "Microsoft Build Engine Started an Unusual Process",
+ "query": "process.parent.name:MSBuild.exe and process.name:(csc.exe or iexplore.exe or powershell.exe)",
+ "references": [
+ "https://blog.talosintelligence.com/2020/02/building-bypass-with-msbuild.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "9d110cb3-5f4b-4c9a-b9f5-53f0a1707ae6",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Windows"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0005",
+ "name": "Defense Evasion",
+ "reference": "https://attack.mitre.org/tactics/TA0005/"
+ },
+ "technique": [
+ {
+ "id": "T1500",
+ "name": "Compile After Delivery",
+ "reference": "https://attack.mitre.org/techniques/T1500/"
+ }
+ ]
+ }
+ ],
+ "type": "query",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_via_compiled_html_file.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_via_compiled_html_file.json
index 7789b0723b3f..2b6e1fb3daae 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_via_compiled_html_file.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_via_compiled_html_file.json
@@ -7,7 +7,6 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Process Activity via Compiled HTML File",
"query": "event.code:1 and process.name:hh.exe",
"risk_score": 21,
@@ -51,4 +50,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_via_net_com_assemblies.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_via_net_com_assemblies.json
new file mode 100644
index 000000000000..c397c955fe64
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_via_net_com_assemblies.json
@@ -0,0 +1,51 @@
+{
+ "description": "RegSvcs.exe and RegAsm.exe are Windows command line utilities that are used to register .NET Component Object Model (COM) assemblies. Adversaries can use RegSvcs.exe and RegAsm.exe to proxy execution of code through a trusted Windows utility.",
+ "index": [
+ "winlogbeat-*"
+ ],
+ "language": "kuery",
+ "max_signals": 33,
+ "name": "Execution via Regsvcs/Regasm",
+ "query": "process.name:(RegAsm.exe or RegSvcs.exe) and event.action:\"Process Create (rule: ProcessCreate)\"",
+ "risk_score": 21,
+ "rule_id": "47f09343-8d1f-4bb5-8bb0-00c9d18f5010",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Windows"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0002",
+ "name": "Execution",
+ "reference": "https://attack.mitre.org/tactics/TA0002/"
+ },
+ "technique": [
+ {
+ "id": "T1121",
+ "name": "Regsvcs/Regasm",
+ "reference": "https://attack.mitre.org/techniques/T1121/"
+ }
+ ]
+ },
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0005",
+ "name": "Defense Evasion",
+ "reference": "https://attack.mitre.org/tactics/TA0005/"
+ },
+ "technique": [
+ {
+ "id": "T1121",
+ "name": "Regsvcs/Regasm",
+ "reference": "https://attack.mitre.org/techniques/T1121/"
+ }
+ ]
+ }
+ ],
+ "type": "query",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_via_trusted_developer_utilities.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_via_trusted_developer_utilities.json
index bd2376a0897f..f60a986996d6 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_via_trusted_developer_utilities.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_execution_via_trusted_developer_utilities.json
@@ -7,9 +7,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Trusted Developer Application Usage",
- "query": "event.code:1 and (process.name:MSBuild.exe or process.name:msxsl.exe)",
+ "query": "event.code:1 and process.name:(MSBuild.exe or msxsl.exe)",
"risk_score": 21,
"rule_id": "9d110cb3-5f4b-4c9a-b9f5-53f0a1707ae1",
"severity": "low",
@@ -51,4 +50,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_html_help_executable_program_connecting_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_html_help_executable_program_connecting_to_the_internet.json
index 32fa953388be..4b3efead776d 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_html_help_executable_program_connecting_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_html_help_executable_program_connecting_to_the_internet.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Network Connection via Compiled HTML File",
- "query": "process.name:hh.exe and event.action:\"Network connection detected (rule: NetworkConnect)\" and not destination.ip:10.0.0.0/8 and not destination.ip:172.16.0.0/12 and not destination.ip:192.168.0.0/16",
+ "query": "process.name:hh.exe and event.action:\"Network connection detected (rule: NetworkConnect)\" and not destination.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)",
"risk_score": 21,
"rule_id": "b29ee2be-bf99-446c-ab1a-2dc0183394b8",
"severity": "low",
@@ -48,4 +47,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_injection_msbuild.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_injection_msbuild.json
new file mode 100644
index 000000000000..c6310c12ed97
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_injection_msbuild.json
@@ -0,0 +1,53 @@
+{
+ "description": "An instance of MSBuild, the Microsoft Build Engine, created a thread in another process. This technique is sometimes used to evade detection or elevate privileges.",
+ "false_positives": [
+ "The Build Engine is commonly used by Windows developers but use by non-engineers is unusual."
+ ],
+ "index": [
+ "winlogbeat-*"
+ ],
+ "language": "kuery",
+ "name": "Process Injection by the Microsoft Build Engine",
+ "query": "process.name:MSBuild.exe and event.action:\"CreateRemoteThread detected (rule: CreateRemoteThread)\"",
+ "risk_score": 21,
+ "rule_id": "9d110cb3-5f4b-4c9a-b9f5-53f0a1707ae9",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Windows"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0005",
+ "name": "Defense Evasion",
+ "reference": "https://attack.mitre.org/tactics/TA0005/"
+ },
+ "technique": [
+ {
+ "id": "T1055",
+ "name": "Process Injection",
+ "reference": "https://attack.mitre.org/techniques/T1055/"
+ }
+ ]
+ },
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0004",
+ "name": "Privilege Escalation",
+ "reference": "https://attack.mitre.org/tactics/TA0004/"
+ },
+ "technique": [
+ {
+ "id": "T1055",
+ "name": "Process Injection",
+ "reference": "https://attack.mitre.org/techniques/T1055/"
+ }
+ ]
+ }
+ ],
+ "type": "query",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_misc_lolbin_connecting_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_misc_lolbin_connecting_to_the_internet.json
index 0015371f0306..0cd68ba5c1ed 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_misc_lolbin_connecting_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_misc_lolbin_connecting_to_the_internet.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Network Connection via Signed Binary",
- "query": "(process.name:expand.exe or process.name:extrac.exe or process.name:ieexec.exe or process.name:makecab.exe) and event.action:\"Network connection detected (rule: NetworkConnect)\" and not destination.ip:10.0.0.0/8 and not destination.ip:172.16.0.0/12 and not destination.ip:192.168.0.0/16",
+ "query": "process.name:(expand.exe or extrac.exe or ieexec.exe or makecab.exe) and event.action:\"Network connection detected (rule: NetworkConnect)\" and not destination.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)",
"risk_score": 21,
"rule_id": "63e65ec3-43b1-45b0-8f2d-45b34291dc44",
"severity": "low",
@@ -48,4 +47,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_modification_of_boot_config.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_modification_of_boot_config.json
new file mode 100644
index 000000000000..d76122627649
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_modification_of_boot_config.json
@@ -0,0 +1,36 @@
+{
+ "description": "Identifies use of bcdedit.exe to delete boot configuration data. This tactic is sometimes used as by malware or an attacker as a destructive technique.",
+ "index": [
+ "winlogbeat-*"
+ ],
+ "language": "kuery",
+ "max_signals": 33,
+ "name": "Modification of Boot Configuration",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.name:bcdedit.exe and process.args:(/set and (bootstatuspolicy and ignoreallfailures or no and recoveryenabled))",
+ "risk_score": 21,
+ "rule_id": "69c251fb-a5d6-4035-b5ec-40438bd829ff",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Windows"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0005",
+ "name": "Defense Evasion",
+ "reference": "https://attack.mitre.org/tactics/TA0005/"
+ },
+ "technique": [
+ {
+ "id": "T1107",
+ "name": "File Deletion",
+ "reference": "https://attack.mitre.org/techniques/T1107/"
+ }
+ ]
+ }
+ ],
+ "type": "query",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_msxsl_network.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_msxsl_network.json
new file mode 100644
index 000000000000..9b45d03aae37
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_msxsl_network.json
@@ -0,0 +1,36 @@
+{
+ "description": "Identifies msxsl.exe making a network connection. This may indicate adversarial activity as msxsl.exe is often leveraged by adversaries to execute malicious scripts and evade detection.",
+ "index": [
+ "winlogbeat-*"
+ ],
+ "language": "kuery",
+ "max_signals": 33,
+ "name": "Network Connection via MsXsl",
+ "query": "process.name:msxsl.exe and event.action:\"Network connection detected (rule: NetworkConnect)\" and not destination.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)",
+ "risk_score": 21,
+ "rule_id": "b86afe07-0d98-4738-b15d-8d7465f95ff5",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Windows"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0002",
+ "name": "Execution",
+ "reference": "https://attack.mitre.org/tactics/TA0002/"
+ },
+ "technique": [
+ {
+ "id": "T1220",
+ "name": "XSL Script Processing",
+ "reference": "https://attack.mitre.org/techniques/T1220/"
+ }
+ ]
+ }
+ ],
+ "type": "query",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_net_command_system_account.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_net_command_system_account.json
new file mode 100644
index 000000000000..390c9c278905
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_net_command_system_account.json
@@ -0,0 +1,36 @@
+{
+ "description": "Identifies the SYSTEM account using the Net utility. The Net utility is a component of the Windows operating system. It is used in command line operations for control of users, groups, services, and network connections.",
+ "index": [
+ "winlogbeat-*"
+ ],
+ "language": "kuery",
+ "max_signals": 33,
+ "name": "Net command via SYSTEM account",
+ "query": "(process.name:net.exe or process.name:net1.exe and not process.parent.name:net.exe) and user.name:SYSTEM and event.action:\"Process Create (rule: ProcessCreate)\"",
+ "risk_score": 21,
+ "rule_id": "2856446a-34e6-435b-9fb5-f8f040bfa7ed",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Windows"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0007",
+ "name": "Discovery",
+ "reference": "https://attack.mitre.org/tactics/TA0007/"
+ },
+ "technique": [
+ {
+ "id": "T1087",
+ "name": "Account Discovery",
+ "reference": "https://attack.mitre.org/techniques/T1087/"
+ }
+ ]
+ }
+ ],
+ "type": "query",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_persistence_via_application_shimming.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_persistence_via_application_shimming.json
index 6eaac7b9e6ca..0488667d06c8 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_persistence_via_application_shimming.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_persistence_via_application_shimming.json
@@ -4,7 +4,6 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Potential Application Shimming via Sdbinst",
"query": "event.code:1 and process.name:sdbinst.exe",
"risk_score": 21,
@@ -48,4 +47,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_priv_escalation_via_accessibility_features.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_priv_escalation_via_accessibility_features.json
index b2463633b0c5..26f0a0bcc245 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_priv_escalation_via_accessibility_features.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_priv_escalation_via_accessibility_features.json
@@ -4,9 +4,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Potential Modification of Accessibility Binaries",
- "query": "event.code:1 and process.parent.name:winlogon.exe and (process.name:atbroker.exe or process.name:displayswitch.exe or process.name:magnify.exe or process.name:narrator.exe or process.name:osk.exe or process.name:sethc.exe or process.name:utilman.exe)",
+ "query": "event.code:1 and process.parent.name:winlogon.exe and process.name:(atbroker.exe or displayswitch.exe or magnify.exe or narrator.exe or osk.exe or sethc.exe or utilman.exe)",
"risk_score": 21,
"rule_id": "7405ddf1-6c8e-41ce-818f-48bea6bcaed8",
"severity": "low",
@@ -48,4 +47,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_process_discovery_via_tasklist_command.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_process_discovery_via_tasklist_command.json
index a0542ef59d8c..28ebdb44fddd 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_process_discovery_via_tasklist_command.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_process_discovery_via_tasklist_command.json
@@ -7,7 +7,6 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Process Discovery via Tasklist",
"query": "event.code:1 and process.name:tasklist.exe",
"risk_score": 21,
@@ -36,4 +35,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_rare_user_runas_event.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_rare_user_runas_event.json
new file mode 100644
index 000000000000..3dca119b5a28
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_rare_user_runas_event.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "A machine learning job detected an unusual user context switch, using the runas command or similar techniques, which can indicate account takeover or privilege escalation using compromised accounts. Privilege elevation using tools like runas are more commonly used by domain and network administrators than by regular Windows users.",
+ "false_positives": [
+ "Uncommon user privilege elevation activity can be due to an administrator, help desk technician, or a user performing manual troubleshooting or reconfiguration."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "windows_rare_user_runas_event",
+ "name": "Unusual Windows User Privilege Elevation Activity",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "1781d055-5c66-4adf-9d82-fc0fa58449c8",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "ML",
+ "Windows"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_rare_user_type10_remote_login.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_rare_user_type10_remote_login.json
new file mode 100644
index 000000000000..09ff2a0cedf4
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_rare_user_type10_remote_login.json
@@ -0,0 +1,24 @@
+{
+ "anomaly_threshold": 50,
+ "description": "A machine learning job detected an unusual remote desktop protocol (RDP) username, which can indicate account takeover or credentialed persistence using compromised accounts. RDP attacks, such as BlueKeep, also tend to use unusual usernames.",
+ "false_positives": [
+ "Uncommon username activity can be due to an engineer logging onto a server instance in order to perform manual troubleshooting or reconfiguration."
+ ],
+ "from": "now-16m",
+ "interval": "15m",
+ "machine_learning_job_id": "windows_rare_user_type10_remote_login",
+ "name": "Unusual Windows Remote User",
+ "references": [
+ "https://www.elastic.co/guide/en/siem/guide/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "1781d055-5c66-4adf-9e93-fc0fa69550c9",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "ML",
+ "Windows"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_register_server_program_connecting_to_the_internet.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_register_server_program_connecting_to_the_internet.json
index d0f2e809c1aa..920ff28a9a9c 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_register_server_program_connecting_to_the_internet.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_register_server_program_connecting_to_the_internet.json
@@ -1,5 +1,5 @@
{
- "description": "Identifies the native Windows tools regsvr32.exe and regsvr64.exe making a network connection. This may be indicative of an attacker bypassing whitelisting or running arbitrary scripts via a signed Microsoft binary.",
+ "description": "Identifies the native Windows tools regsvr32.exe and regsvr64.exe making a network connection. This may be indicative of an attacker bypassing whitelisting or running arbitrary scripts via a signed Microsoft binary.",
"false_positives": [
"Security testing may produce events like this. Activity of this kind performed by non-engineers and ordinary users is unusual."
],
@@ -7,9 +7,8 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Network Connection via Regsvr",
- "query": "(process.name:regsvr32.exe or process.name:regsvr64.exe) and event.action:\"Network connection detected (rule: NetworkConnect)\" and not destination.ip:169.254.169.254/32 and not destination.ip:10.0.0.0/8 and not destination.ip:172.16.0.0/12 and not destination.ip:192.168.0.0/16",
+ "query": "process.name:(regsvr32.exe or regsvr64.exe) and event.action:\"Network connection detected (rule: NetworkConnect)\" and not destination.ip:(10.0.0.0/8 or 169.254.169.254 or 172.16.0.0/12 or 192.168.0.0/16)",
"risk_score": 21,
"rule_id": "fb02b8d3-71ee-4af1-bacd-215d23f17efa",
"severity": "low",
@@ -51,4 +50,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_suspicious_pdf_reader.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_suspicious_pdf_reader.json
new file mode 100644
index 000000000000..9d4c2438acfb
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_suspicious_pdf_reader.json
@@ -0,0 +1,35 @@
+{
+ "description": "Identifies suspicious child processes of PDF reader applications. These child processes are often launched via exploitation of PDF applications or social engineering.",
+ "index": [
+ "winlogbeat-*"
+ ],
+ "language": "kuery",
+ "name": "Suspicious PDF Reader Child Process",
+ "query": "event.action:\"Process Create (rule: ProcessCreate)\" and process.parent.name:(AcroRd32.exe or Acrobat.exe or FoxitPhantomPDF.exe or FoxitReader.exe) and process.name:(arp.exe or dsquery.exe or dsget.exe or gpresult.exe or hostname.exe or ipconfig.exe or nbtstat.exe or net.exe or net1.exe or netsh.exe or netstat.exe or nltest.exe or ping.exe or qprocess.exe or quser.exe or qwinsta.exe or reg.exe or sc.exe or systeminfo.exe or tasklist.exe or tracert.exe or whoami.exe or bginfo.exe or cdb.exe or cmstp.exe or csi.exe or dnx.exe or fsi.exe or ieexec.exe or iexpress.exe or installutil.exe or Microsoft.Workflow.Compiler.exe or msbuild.exe or mshta.exe or msxsl.exe or odbcconf.exe or rcsi.exe or regsvr32.exe or xwizard.exe or atbroker.exe or forfiles.exe or schtasks.exe or regasm.exe or regsvcs.exe or cmd.exe or cscript.exe or powershell.exe or pwsh.exe or wmic.exe or wscript.exe or bitsadmin.exe or certutil.exe or ftp.exe)",
+ "risk_score": 21,
+ "rule_id": "53a26770-9cbd-40c5-8b57-61d01a325e14",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Windows"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0002",
+ "name": "Execution",
+ "reference": "https://attack.mitre.org/tactics/TA0002/"
+ },
+ "technique": [
+ {
+ "id": "T1204",
+ "name": "User Execution",
+ "reference": "https://attack.mitre.org/techniques/T1204/"
+ }
+ ]
+ }
+ ],
+ "type": "query",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_uac_bypass_event_viewer.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_uac_bypass_event_viewer.json
new file mode 100644
index 000000000000..0d4168640bc6
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_uac_bypass_event_viewer.json
@@ -0,0 +1,36 @@
+{
+ "description": "Identifies User Account Control (UAC) bypass via eventvwr.exe. Attackers bypass UAC to stealthily execute code with elevated permissions.",
+ "index": [
+ "winlogbeat-*"
+ ],
+ "language": "kuery",
+ "max_signals": 33,
+ "name": "Bypass UAC via Event Viewer",
+ "query": "process.parent.name:eventvwr.exe and event.action:\"Process Create (rule: ProcessCreate)\" and not process.executable:(\"C:\\Windows\\SysWOW64\\mmc.exe\" or \"C:\\Windows\\System32\\mmc.exe\")",
+ "risk_score": 21,
+ "rule_id": "31b4c719-f2b4-41f6-a9bd-fce93c2eaf62",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Windows"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0004",
+ "name": "Privilege Escalation",
+ "reference": "https://attack.mitre.org/tactics/TA0004/"
+ },
+ "technique": [
+ {
+ "id": "T1088",
+ "name": "Bypass User Account Control",
+ "reference": "https://attack.mitre.org/techniques/T1088/"
+ }
+ ]
+ }
+ ],
+ "type": "query",
+ "version": 1
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_whoami_command_activity.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_whoami_command_activity.json
index 678160f945ba..46af0c5b586a 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_whoami_command_activity.json
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules/windows_whoami_command_activity.json
@@ -7,7 +7,6 @@
"winlogbeat-*"
],
"language": "kuery",
- "max_signals": 100,
"name": "Whoami Process Activity",
"query": "process.name:whoami.exe and event.code:1",
"risk_score": 21,
@@ -36,4 +35,4 @@
],
"type": "query",
"version": 1
-}
+}
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts
index d8dacc7c6439..38b1097a845f 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts
@@ -142,12 +142,12 @@ export interface Clients {
actionsClient: ActionsClient;
}
-export type PatchRuleParams = Partial & {
+export type PatchRuleParams = Partial> & {
id: string | undefined | null;
savedObjectsClient: SavedObjectsClientContract;
} & Clients;
-export type UpdateRuleParams = RuleAlertParams & {
+export type UpdateRuleParams = Omit & {
id: string | undefined | null;
savedObjectsClient: SavedObjectsClientContract;
} & Clients;
@@ -157,7 +157,9 @@ export type DeleteRuleParams = Clients & {
ruleId: string | undefined | null;
};
-export type CreateRuleParams = Omit & { ruleId: string } & Clients;
+export type CreateRuleParams = Omit & {
+ ruleId: string;
+} & Clients;
export interface ReadRuleParams {
alertsClient: AlertsClient;
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_prepacked_rules.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_prepacked_rules.test.ts
new file mode 100644
index 000000000000..7a3f23347511
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_prepacked_rules.test.ts
@@ -0,0 +1,62 @@
+/*
+ * 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 { savedObjectsClientMock } from '../../../../../../../../src/core/server/mocks';
+import { alertsClientMock } from '../../../../../../../plugins/alerting/server/mocks';
+import { actionsClientMock } from '../../../../../../../plugins/actions/server/mocks';
+import { mockPrepackagedRule } from '../routes/__mocks__/request_responses';
+import { updatePrepackagedRules } from './update_prepacked_rules';
+import { patchRules } from './patch_rules';
+jest.mock('./patch_rules');
+
+describe('updatePrepackagedRules', () => {
+ let actionsClient: ReturnType;
+ let alertsClient: ReturnType;
+ let savedObjectsClient: ReturnType;
+
+ beforeEach(() => {
+ actionsClient = actionsClientMock.create();
+ alertsClient = alertsClientMock.create();
+ savedObjectsClient = savedObjectsClientMock.create();
+ });
+
+ it('should omit actions and enabled when calling patchRules', async () => {
+ const actions = [
+ {
+ group: 'group',
+ id: 'id',
+ action_type_id: 'action_type_id',
+ params: {},
+ },
+ ];
+ const outputIndex = 'outputIndex';
+ const prepackagedRule = mockPrepackagedRule();
+
+ await updatePrepackagedRules(
+ alertsClient,
+ actionsClient,
+ savedObjectsClient,
+ [{ ...prepackagedRule, actions }],
+ outputIndex
+ );
+
+ expect(patchRules).toHaveBeenCalledWith(
+ expect.objectContaining({
+ ruleId: 'rule-1',
+ })
+ );
+ expect(patchRules).not.toHaveBeenCalledWith(
+ expect.objectContaining({
+ enabled: true,
+ })
+ );
+ expect(patchRules).not.toHaveBeenCalledWith(
+ expect.objectContaining({
+ actions,
+ })
+ );
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_prepacked_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_prepacked_rules.ts
index cc67622176a0..7eb0d8d1399b 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_prepacked_rules.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_prepacked_rules.ts
@@ -19,7 +19,6 @@ export const updatePrepackagedRules = async (
): Promise => {
await rules.forEach(async rule => {
const {
- actions,
description,
false_positives: falsePositives,
from,
@@ -40,7 +39,6 @@ export const updatePrepackagedRules = async (
to,
type,
threat,
- throttle,
references,
version,
note,
@@ -51,7 +49,6 @@ export const updatePrepackagedRules = async (
return patchRules({
alertsClient,
actionsClient,
- actions,
description,
falsePositives,
from,
@@ -75,7 +72,6 @@ export const updatePrepackagedRules = async (
to,
type,
threat,
- throttle,
references,
version,
note,
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rule_actions.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rule_actions.ts
new file mode 100644
index 000000000000..ac10143c1d8d
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rule_actions.ts
@@ -0,0 +1,50 @@
+/*
+ * 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 { AlertsClient, AlertServices } from '../../../../../../../plugins/alerting/server';
+import { getRuleActionsSavedObject } from '../rule_actions/get_rule_actions_saved_object';
+import { readRules } from './read_rules';
+import { transformRuleToAlertAction } from '../../../../common/detection_engine/transform_actions';
+
+interface UpdateRuleActions {
+ alertsClient: AlertsClient;
+ savedObjectsClient: AlertServices['savedObjectsClient'];
+ ruleAlertId: string;
+}
+
+export const updateRuleActions = async ({
+ alertsClient,
+ savedObjectsClient,
+ ruleAlertId,
+}: UpdateRuleActions) => {
+ const rule = await readRules({ alertsClient, id: ruleAlertId });
+ if (rule == null) {
+ return null;
+ }
+
+ const ruleActions = await getRuleActionsSavedObject({
+ savedObjectsClient,
+ ruleAlertId,
+ });
+
+ if (!ruleActions) {
+ return null;
+ }
+
+ return alertsClient.update({
+ id: ruleAlertId,
+ data: {
+ actions: !ruleActions.alertThrottle
+ ? ruleActions.actions.map(transformRuleToAlertAction)
+ : [],
+ throttle: null,
+ name: rule.name,
+ tags: rule.tags,
+ schedule: rule.schedule,
+ params: rule.params,
+ },
+ });
+};
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.test.ts
index af00816abfc3..ca299db6ace5 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.test.ts
@@ -28,12 +28,10 @@ describe('updateRules', () => {
await updateRules({
alertsClient,
actionsClient,
- actions: [],
savedObjectsClient,
id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
...rule.params,
enabled: false,
- throttle: null,
interval: '',
name: '',
tags: [],
@@ -56,12 +54,10 @@ describe('updateRules', () => {
await updateRules({
alertsClient,
actionsClient,
- actions: [],
savedObjectsClient,
id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
...rule.params,
enabled: true,
- throttle: null,
interval: '',
name: '',
tags: [],
@@ -86,12 +82,10 @@ describe('updateRules', () => {
await updateRules({
alertsClient,
actionsClient,
- actions: [],
savedObjectsClient,
id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
...params,
enabled: true,
- throttle: null,
interval: '',
name: '',
tags: [],
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.ts
index 72cbc959c010..0e70e05f4de7 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.ts
@@ -5,7 +5,6 @@
*/
import { PartialAlert } from '../../../../../../../plugins/alerting/server';
-import { transformRuleToAlertAction } from '../../../../common/detection_engine/transform_actions';
import { readRules } from './read_rules';
import { IRuleSavedAttributesSavedObjectAttributes, UpdateRuleParams } from './types';
import { addTags } from './add_tags';
@@ -16,7 +15,6 @@ import { hasListsFeature } from '../feature_flags';
export const updateRules = async ({
alertsClient,
actionsClient, // TODO: Use this whenever we add feature support for different action types
- actions,
savedObjectsClient,
description,
falsePositives,
@@ -30,7 +28,6 @@ export const updateRules = async ({
meta,
filters,
from,
- immutable,
id,
ruleId,
index,
@@ -41,7 +38,6 @@ export const updateRules = async ({
severity,
tags,
threat,
- throttle,
to,
type,
references,
@@ -57,7 +53,6 @@ export const updateRules = async ({
}
const calculatedVersion = calculateVersion(rule.params.immutable, rule.params.version, {
- actions,
description,
falsePositives,
query,
@@ -77,7 +72,6 @@ export const updateRules = async ({
severity,
tags,
threat,
- throttle,
to,
type,
references,
@@ -93,17 +87,17 @@ export const updateRules = async ({
const update = await alertsClient.update({
id: rule.id,
data: {
- tags: addTags(tags, rule.params.ruleId, immutable),
+ tags: addTags(tags, rule.params.ruleId, rule.params.immutable),
name,
schedule: { interval },
- actions: actions?.map(transformRuleToAlertAction) ?? rule.actions,
- throttle: throttle !== undefined ? throttle : rule.throttle,
+ actions: rule.actions,
+ throttle: rule.throttle,
params: {
description,
ruleId: rule.params.ruleId,
falsePositives,
from,
- immutable,
+ immutable: rule.params.immutable,
query,
language,
outputIndex,
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules_notifications.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules_notifications.ts
new file mode 100644
index 000000000000..f70c591243a7
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules_notifications.ts
@@ -0,0 +1,55 @@
+/*
+ * 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 { RuleAlertAction } from '../../../../common/detection_engine/types';
+import { AlertsClient, AlertServices } from '../../../../../../../plugins/alerting/server';
+import { updateOrCreateRuleActionsSavedObject } from '../rule_actions/update_or_create_rule_actions_saved_object';
+import { updateNotifications } from '../notifications/update_notifications';
+import { updateRuleActions } from './update_rule_actions';
+
+interface UpdateRulesNotifications {
+ alertsClient: AlertsClient;
+ savedObjectsClient: AlertServices['savedObjectsClient'];
+ ruleAlertId: string;
+ actions: RuleAlertAction[] | undefined;
+ throttle: string | undefined;
+ enabled: boolean;
+ name: string;
+}
+
+export const updateRulesNotifications = async ({
+ alertsClient,
+ savedObjectsClient,
+ ruleAlertId,
+ actions,
+ enabled,
+ name,
+ throttle,
+}: UpdateRulesNotifications) => {
+ const ruleActions = await updateOrCreateRuleActionsSavedObject({
+ savedObjectsClient,
+ ruleAlertId,
+ actions,
+ throttle,
+ });
+
+ await updateRuleActions({
+ alertsClient,
+ savedObjectsClient,
+ ruleAlertId,
+ });
+
+ await updateNotifications({
+ alertsClient,
+ ruleAlertId,
+ enabled,
+ name,
+ actions: ruleActions.actions,
+ interval: ruleActions?.alertThrottle,
+ });
+
+ return ruleActions;
+};
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_bulk_body.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_bulk_body.test.ts
index c86696d6ec5e..f2c2b99bdac8 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_bulk_body.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_bulk_body.test.ts
@@ -33,7 +33,7 @@ describe('buildBulkBody', () => {
interval: '5m',
enabled: true,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
// Timestamp will potentially always be different so remove it for the test
delete fakeSignalSourceHit['@timestamp'];
@@ -80,6 +80,7 @@ describe('buildBulkBody', () => {
references: ['http://google.com'],
severity: 'high',
tags: ['some fake tag 1', 'some fake tag 2'],
+ throttle: 'no_actions',
type: 'query',
to: 'now',
note: '',
@@ -143,7 +144,7 @@ describe('buildBulkBody', () => {
interval: '5m',
enabled: true,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
// Timestamp will potentially always be different so remove it for the test
delete fakeSignalSourceHit['@timestamp'];
@@ -208,6 +209,7 @@ describe('buildBulkBody', () => {
version: 1,
created_at: fakeSignalSourceHit.signal.rule?.created_at,
updated_at: fakeSignalSourceHit.signal.rule?.updated_at,
+ throttle: 'no_actions',
lists: [
{
field: 'source.ip',
@@ -261,7 +263,7 @@ describe('buildBulkBody', () => {
interval: '5m',
enabled: true,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
// Timestamp will potentially always be different so remove it for the test
delete fakeSignalSourceHit['@timestamp'];
@@ -325,6 +327,7 @@ describe('buildBulkBody', () => {
version: 1,
created_at: fakeSignalSourceHit.signal.rule?.created_at,
updated_at: fakeSignalSourceHit.signal.rule?.updated_at,
+ throttle: 'no_actions',
lists: [
{
field: 'source.ip',
@@ -376,7 +379,7 @@ describe('buildBulkBody', () => {
interval: '5m',
enabled: true,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
// Timestamp will potentially always be different so remove it for the test
delete fakeSignalSourceHit['@timestamp'];
@@ -435,6 +438,7 @@ describe('buildBulkBody', () => {
version: 1,
updated_at: fakeSignalSourceHit.signal.rule?.updated_at,
created_at: fakeSignalSourceHit.signal.rule?.created_at,
+ throttle: 'no_actions',
lists: [
{
field: 'source.ip',
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_bulk_body.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_bulk_body.ts
index f485769dffab..75c4d75cedf1 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_bulk_body.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_bulk_body.ts
@@ -24,7 +24,7 @@ interface BuildBulkBodyParams {
interval: string;
enabled: boolean;
tags: string[];
- throttle: string | null;
+ throttle: string;
}
// format search_after result for signals index.
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_rule.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_rule.test.ts
index 37d7ed8a5108..e360ceaf02f4 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_rule.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_rule.test.ts
@@ -38,7 +38,7 @@ describe('buildRule', () => {
updatedBy: 'elastic',
interval: 'some interval',
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
const expected: Partial = {
actions: [],
@@ -67,6 +67,7 @@ describe('buildRule', () => {
updated_by: 'elastic',
updated_at: rule.updated_at,
created_at: rule.created_at,
+ throttle: 'no_actions',
filters: [
{
query: 'host.name: Rebecca',
@@ -124,7 +125,7 @@ describe('buildRule', () => {
updatedBy: 'elastic',
interval: 'some interval',
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
const expected: Partial = {
actions: [],
@@ -154,6 +155,7 @@ describe('buildRule', () => {
version: 1,
updated_at: rule.updated_at,
created_at: rule.created_at,
+ throttle: 'no_actions',
lists: [
{
field: 'source.ip',
@@ -199,7 +201,7 @@ describe('buildRule', () => {
updatedBy: 'elastic',
interval: 'some interval',
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
const expected: Partial = {
actions: [],
@@ -229,80 +231,7 @@ describe('buildRule', () => {
version: 1,
updated_at: rule.updated_at,
created_at: rule.created_at,
- lists: [
- {
- field: 'source.ip',
- boolean_operator: 'and',
- values: [
- {
- name: '127.0.0.1',
- type: 'value',
- },
- ],
- },
- {
- field: 'host.name',
- boolean_operator: 'and not',
- values: [
- {
- name: 'rock01',
- type: 'value',
- },
- {
- name: 'mothra',
- type: 'value',
- },
- ],
- },
- ],
- };
- expect(rule).toEqual(expected);
- });
-
- test('it omits a null value such as if "throttle" is undefined if is present', () => {
- const ruleParams = sampleRuleAlertParams();
- const rule = buildRule({
- actions: [],
- ruleParams,
- name: 'some-name',
- id: sampleRuleGuid,
- enabled: true,
- createdAt: '2020-01-28T15:58:34.810Z',
- updatedAt: '2020-01-28T15:59:14.004Z',
- createdBy: 'elastic',
- updatedBy: 'elastic',
- interval: 'some interval',
- tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
- });
- const expected: Partial = {
- actions: [],
- 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',
- note: '',
- updated_by: 'elastic',
- version: 1,
- updated_at: rule.updated_at,
- created_at: rule.created_at,
+ throttle: 'no_actions',
lists: [
{
field: 'source.ip',
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_rule.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_rule.ts
index 1de80ca0b7ea..9c375d7d45d5 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_rule.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_rule.ts
@@ -20,7 +20,7 @@ interface BuildRuleParams {
updatedBy: string;
interval: string;
tags: string[];
- throttle: string | null;
+ throttle: string;
}
export const buildRule = ({
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/bulk_create_ml_signals.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/bulk_create_ml_signals.ts
index c1b61ef24462..355041d9efbd 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/bulk_create_ml_signals.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/bulk_create_ml_signals.ts
@@ -30,7 +30,7 @@ interface BulkCreateMlSignalsParams {
interval: string;
enabled: boolean;
tags: string[];
- throttle: string | null;
+ throttle: string;
}
interface EcsAnomaly extends Anomaly {
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.test.ts
index b12c21b7a5b5..06652028b374 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.test.ts
@@ -53,7 +53,7 @@ describe('searchAfterAndBulkCreate', () => {
pageSize: 1,
filter: undefined,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
expect(mockService.callCluster).toHaveBeenCalledTimes(0);
expect(success).toEqual(true);
@@ -111,7 +111,7 @@ describe('searchAfterAndBulkCreate', () => {
pageSize: 1,
filter: undefined,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
expect(mockService.callCluster).toHaveBeenCalledTimes(5);
expect(success).toEqual(true);
@@ -140,7 +140,7 @@ describe('searchAfterAndBulkCreate', () => {
pageSize: 1,
filter: undefined,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
expect(mockLogger.error).toHaveBeenCalled();
expect(success).toEqual(false);
@@ -176,7 +176,7 @@ describe('searchAfterAndBulkCreate', () => {
pageSize: 1,
filter: undefined,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
expect(mockLogger.error).toHaveBeenCalled();
expect(success).toEqual(false);
@@ -212,7 +212,7 @@ describe('searchAfterAndBulkCreate', () => {
pageSize: 1,
filter: undefined,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
expect(success).toEqual(true);
});
@@ -250,7 +250,7 @@ describe('searchAfterAndBulkCreate', () => {
pageSize: 1,
filter: undefined,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
expect(success).toEqual(true);
});
@@ -288,7 +288,7 @@ describe('searchAfterAndBulkCreate', () => {
pageSize: 1,
filter: undefined,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
expect(success).toEqual(true);
});
@@ -328,7 +328,7 @@ describe('searchAfterAndBulkCreate', () => {
pageSize: 1,
filter: undefined,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
expect(success).toEqual(false);
});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.ts
index ff263333fb79..a5d5dd0a7b71 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.ts
@@ -31,7 +31,7 @@ interface SearchAfterAndBulkCreateParams {
pageSize: number;
filter: unknown;
tags: string[];
- throttle: string | null;
+ throttle: string;
}
export interface SearchAfterAndBulkCreateReturnType {
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/signal_rule_alert_type.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/signal_rule_alert_type.ts
index de4ec68e8fc8..78b0cd84eeda 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/signal_rule_alert_type.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/signal_rule_alert_type.ts
@@ -7,11 +7,7 @@
import { performance } from 'perf_hooks';
import { Logger } from 'src/core/server';
-import {
- SIGNALS_ID,
- DEFAULT_SEARCH_AFTER_PAGE_SIZE,
- NOTIFICATION_THROTTLE_RULE,
-} from '../../../../common/constants';
+import { SIGNALS_ID, DEFAULT_SEARCH_AFTER_PAGE_SIZE } from '../../../../common/constants';
import { isJobStarted, isMlRule } from '../../../../common/detection_engine/ml_helpers';
import { SetupPlugins } from '../../../plugin';
@@ -244,7 +240,7 @@ export const signalRulesAlertType = ({
}
if (result.success) {
- if (meta?.throttle === NOTIFICATION_THROTTLE_RULE && actions.length) {
+ if (actions.length) {
const notificationRuleParams = {
...ruleParams,
name,
@@ -255,7 +251,7 @@ export const signalRulesAlertType = ({
to: 'now',
index: ruleParams.outputIndex,
ruleId: ruleParams.ruleId!,
- kibanaSiemAppUrl: meta.kibanaSiemAppUrl as string,
+ kibanaSiemAppUrl: meta?.kibanaSiemAppUrl as string,
ruleAlertId: savedObject.id,
callCluster: services.callCluster,
});
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.test.ts
index 93f9c24a057f..45b5610e2d3c 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.test.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.test.ts
@@ -160,7 +160,7 @@ describe('singleBulkCreate', () => {
interval: '5m',
enabled: true,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
expect(success).toEqual(true);
});
@@ -192,7 +192,7 @@ describe('singleBulkCreate', () => {
interval: '5m',
enabled: true,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
expect(success).toEqual(true);
});
@@ -216,7 +216,7 @@ describe('singleBulkCreate', () => {
interval: '5m',
enabled: true,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
expect(success).toEqual(true);
});
@@ -241,7 +241,7 @@ describe('singleBulkCreate', () => {
interval: '5m',
enabled: true,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
expect(mockLogger.error).not.toHaveBeenCalled();
@@ -268,7 +268,7 @@ describe('singleBulkCreate', () => {
interval: '5m',
enabled: true,
tags: ['some fake tag 1', 'some fake tag 2'],
- throttle: null,
+ throttle: 'no_actions',
});
expect(mockLogger.error).toHaveBeenCalled();
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.ts
index 0192ff76efa5..ffec40b839bf 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.ts
@@ -30,7 +30,7 @@ interface SingleBulkCreateParams {
interval: string;
enabled: boolean;
tags: string[];
- throttle: string | null;
+ throttle: string;
}
/**
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/types.ts
index 93c48ed38c7c..543e8bf0619b 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/types.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/types.ts
@@ -158,7 +158,7 @@ export interface AlertAttributes {
schedule: {
interval: string;
};
- throttle: string | null;
+ throttle: string;
}
export interface RuleAlertAttributes extends AlertAttributes {
diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/types.ts
index 08b3f864314f..efa0a92cc573 100644
--- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/types.ts
+++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/types.ts
@@ -60,7 +60,7 @@ export interface RuleAlertParams {
threat: ThreatParams[] | undefined | null;
type: RuleType;
version: number;
- throttle: string | null;
+ throttle: string;
lists: ListsDefaultArraySchema | null | undefined;
}
@@ -118,7 +118,6 @@ export type OutputRuleAlertRest = RuleAlertParamsRest & {
created_by: string | undefined | null;
updated_by: string | undefined | null;
immutable: boolean;
- throttle: string | undefined | null;
};
export type ImportRuleAlertRest = Omit & {
diff --git a/x-pack/legacy/plugins/siem/server/plugin.ts b/x-pack/legacy/plugins/siem/server/plugin.ts
index 2235207070fe..13b58fa1d57e 100644
--- a/x-pack/legacy/plugins/siem/server/plugin.ts
+++ b/x-pack/legacy/plugins/siem/server/plugin.ts
@@ -36,6 +36,7 @@ import {
pinnedEventSavedObjectType,
timelineSavedObjectType,
ruleStatusSavedObjectType,
+ ruleActionsSavedObjectType,
} from './saved_objects';
import { SiemClientFactory } from './client';
import { hasListsFeature, listsEnvFeatureFlagName } from './lib/detection_engine/feature_flags';
@@ -121,6 +122,7 @@ export class Plugin {
pinnedEventSavedObjectType,
timelineSavedObjectType,
ruleStatusSavedObjectType,
+ ruleActionsSavedObjectType,
'cases',
'cases-comments',
'cases-configure',
@@ -151,6 +153,7 @@ export class Plugin {
pinnedEventSavedObjectType,
timelineSavedObjectType,
ruleStatusSavedObjectType,
+ ruleActionsSavedObjectType,
'cases',
'cases-comments',
'cases-configure',
diff --git a/x-pack/legacy/plugins/siem/server/saved_objects.ts b/x-pack/legacy/plugins/siem/server/saved_objects.ts
index 76d8837883b8..7b097eefedb4 100644
--- a/x-pack/legacy/plugins/siem/server/saved_objects.ts
+++ b/x-pack/legacy/plugins/siem/server/saved_objects.ts
@@ -17,11 +17,16 @@ import {
ruleStatusSavedObjectMappings,
ruleStatusSavedObjectType,
} from './lib/detection_engine/rules/saved_object_mappings';
+import {
+ ruleActionsSavedObjectMappings,
+ ruleActionsSavedObjectType,
+} from './lib/detection_engine/rule_actions/saved_object_mappings';
export {
noteSavedObjectType,
pinnedEventSavedObjectType,
ruleStatusSavedObjectType,
+ ruleActionsSavedObjectType,
timelineSavedObjectType,
};
export const savedObjectMappings = {
@@ -29,4 +34,5 @@ export const savedObjectMappings = {
...noteSavedObjectMappings,
...pinnedEventSavedObjectMappings,
...ruleStatusSavedObjectMappings,
+ ...ruleActionsSavedObjectMappings,
};
diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/typeahead/index.js b/x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/typeahead/index.js
index 9b8bdb50441c..0ea5e1e2b837 100644
--- a/x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/typeahead/index.js
+++ b/x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/typeahead/index.js
@@ -27,6 +27,7 @@ export class Typeahead extends Component {
index: null,
value: '',
inputIsPristine: true,
+ lastSubmitted: '',
};
static getDerivedStateFromProps(props, state) {
@@ -151,7 +152,10 @@ export class Typeahead extends Component {
};
onSubmit = () => {
- this.props.onSubmit(this.state.value);
+ if (this.state.lastSubmitted !== this.state.value) {
+ this.props.onSubmit(this.state.value);
+ this.setState({ lastSubmitted: this.state.value });
+ }
this.setState({ isSuggestionsVisible: false });
};
@@ -177,6 +181,7 @@ export class Typeahead extends Component {
value={this.state.value}
onKeyDown={this.onKeyDown}
onKeyUp={this.onKeyUp}
+ onBlur={this.onSubmit}
onChange={this.onChangeInputValue}
onClick={this.onClickInput}
autoComplete="off"
diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/embedded_map.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/embedded_map.tsx
index cfed52f4e5d2..168d71a31dd4 100644
--- a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/embedded_map.tsx
+++ b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/embedded_map.tsx
@@ -7,9 +7,9 @@
import React, { useEffect, useState, useContext, useRef } from 'react';
import uuid from 'uuid';
import styled from 'styled-components';
+import { npStart } from 'ui/new_platform';
import { ViewMode } from '../../../../../../../../../src/plugins/embeddable/public';
-import { start } from '../../../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public/legacy';
import * as i18n from './translations';
import { MapEmbeddable, MapEmbeddableInput } from '../../../../../../maps/public';
import { MAP_SAVED_OBJECT_TYPE } from '../../../../../../../../plugins/maps/public';
@@ -47,7 +47,7 @@ export const EmbeddedMap = React.memo(({ upPoints, downPoints }: EmbeddedMapProp
const { colors } = useContext(UptimeThemeContext);
const [embeddable, setEmbeddable] = useState();
const embeddableRoot: React.RefObject = useRef(null);
- const factory = start.getEmbeddableFactory(MAP_SAVED_OBJECT_TYPE);
+ const factory = npStart.plugins.embeddable.getEmbeddableFactory(MAP_SAVED_OBJECT_TYPE);
const input: MapEmbeddableInput = {
id: uuid.v4(),
diff --git a/x-pack/plugins/endpoint/package.json b/x-pack/plugins/endpoint/package.json
index fc4f4bd586be..9e65f23a3886 100644
--- a/x-pack/plugins/endpoint/package.json
+++ b/x-pack/plugins/endpoint/package.json
@@ -13,6 +13,7 @@
"devDependencies": {
"@types/seedrandom": ">=2.0.0 <4.0.0",
"@types/react-redux": "^7.1.0",
- "redux-devtools-extension": "^2.13.8"
+ "redux-devtools-extension": "^2.13.8",
+ "ts-node": "^8.8.1"
}
}
diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/actions.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/actions.ts
index ceb5da2ca909..0860c9c62aca 100644
--- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/actions.ts
+++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/actions.ts
@@ -43,6 +43,7 @@ interface UserChangedSelectedEvent {
interface AppRequestedResolverData {
readonly type: 'appRequestedResolverData';
}
+
/**
* When the user switches the active descendent of the Resolver.
*/
@@ -50,7 +51,7 @@ interface UserFocusedOnResolverNode {
readonly type: 'userFocusedOnResolverNode';
readonly payload: {
/**
- * Used to identify the process node that should be brought into view.
+ * Used to identify the process node that the user focused on (in the DOM)
*/
readonly nodeId: string;
};
diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/defs.tsx b/x-pack/plugins/endpoint/public/embeddables/resolver/view/defs.tsx
index 3295ef028923..911cda1be651 100644
--- a/x-pack/plugins/endpoint/public/embeddables/resolver/view/defs.tsx
+++ b/x-pack/plugins/endpoint/public/embeddables/resolver/view/defs.tsx
@@ -13,6 +13,7 @@ import {
euiPaletteForStatus,
colorPalette,
} from '@elastic/eui';
+import styled from 'styled-components';
/**
* Generating from `colorPalette` function: This could potentially
@@ -396,17 +397,25 @@ const SymbolsAndShapes = memo(() => (
));
/**
- * This element is used to define the reusable assets for the Resolver
- * It confers sevral advantages, including but not limited to:
- * 1) Freedom of form for creative assets (beyond box-model constraints)
- * 2) Separation of concerns between creative assets and more functional areas of the app
- * 3)
{entityControls.map(entity => {
const entityKey = `${entity.fieldName}`;
- const forceSelection = !hasEmptyFieldValues && !entity.fieldValue;
+ const forceSelection = !hasEmptyFieldValues && entity.fieldValue === null;
hasEmptyFieldValues = !hasEmptyFieldValues && forceSelection;
return (
{
if (!interval) {
- throw new Error('Interval is required to retrieve max bucket cardinalities.');
+ throw Boom.badRequest('Interval is required to retrieve max bucket cardinalities.');
}
const aggregatableFields = await getAggregatableFields(index, fieldNames);
@@ -243,12 +260,17 @@ export function fieldsServiceProvider(callAsCurrentUser: APICaller) {
return {};
}
+ const { start, end } = getSafeTimeRangeForInterval(
+ interval,
+ ...Object.values(getSafeTimeRange(earliestMs, latestMs))
+ );
+
const cachedValues =
fieldsAggsCache.getValues(
index,
timeFieldName,
- earliestMs,
- latestMs,
+ start,
+ end,
'maxBucketCardinality',
fieldNames
) ?? {};
@@ -260,8 +282,6 @@ export function fieldsServiceProvider(callAsCurrentUser: APICaller) {
return cachedValues;
}
- const { start, end } = getSafeTimeRange(earliestMs, latestMs, interval);
-
const mustCriteria = [
{
range: {
@@ -334,6 +354,10 @@ export function fieldsServiceProvider(callAsCurrentUser: APICaller) {
return obj;
}, {} as { [field: string]: number });
+ fieldsAggsCache.updateValues(index, timeFieldName, start, end, {
+ maxBucketCardinality: aggResult,
+ });
+
return {
...cachedValues,
...aggResult,
diff --git a/x-pack/plugins/ml/server/routes/calendars.ts b/x-pack/plugins/ml/server/routes/calendars.ts
index 63984728a18d..34950c6ed79f 100644
--- a/x-pack/plugins/ml/server/routes/calendars.ts
+++ b/x-pack/plugins/ml/server/routes/calendars.ts
@@ -42,6 +42,7 @@ function getCalendarsByIds(context: RequestHandlerContext, calendarIds: string)
}
export function calendars({ router, mlLicense }: RouteInitialization) {
+ // Gets calendars - size limit has been explicitly set to 1000
router.get(
{
path: '/api/ml/calendars',
diff --git a/x-pack/plugins/ml/server/routes/filters.ts b/x-pack/plugins/ml/server/routes/filters.ts
index 2f823d79a8e5..e827ed96b12a 100644
--- a/x-pack/plugins/ml/server/routes/filters.ts
+++ b/x-pack/plugins/ml/server/routes/filters.ts
@@ -47,7 +47,7 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) {
/**
* @apiGroup Filters
*
- * @api {get} /api/ml/filters Gets filters
+ * @api {get} /api/ml/filters Gets filters - size limit has been explicitly set to 1000
* @apiName GetFilters
* @apiDescription Retrieves the list of filters which are used for custom rules in anomaly detection.
*
diff --git a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx
index 282ee75815fa..d4e3069186f6 100644
--- a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx
+++ b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx
@@ -11,10 +11,7 @@ import { Action, IncompatibleActionError } from '../../../../../src/plugins/ui_a
import { LicensingPluginSetup } from '../../../licensing/public';
import { checkLicense } from '../lib/license_check';
-import {
- ViewMode,
- IEmbeddable,
-} from '../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public';
+import { ViewMode, IEmbeddable } from '../../../../../src/plugins/embeddable/public';
// @TODO: These import paths will need to be updated once discovery moves to non-legacy dir
import { SEARCH_EMBEDDABLE_TYPE } from '../../../../../src/legacy/core_plugins/kibana/public/discover/np_ready/embeddable/constants';
diff --git a/x-pack/plugins/transform/public/app/components/pivot_preview/pivot_preview.tsx b/x-pack/plugins/transform/public/app/components/pivot_preview/pivot_preview.tsx
index 51ca9f38a3d1..7965eeb779a3 100644
--- a/x-pack/plugins/transform/public/app/components/pivot_preview/pivot_preview.tsx
+++ b/x-pack/plugins/transform/public/app/components/pivot_preview/pivot_preview.tsx
@@ -163,6 +163,7 @@ export const PivotPreview: FC = React.memo(
schema = 'boolean';
break;
case ES_FIELD_TYPES.DATE:
+ case ES_FIELD_TYPES.DATE_NANOS:
schema = 'datetime';
break;
case ES_FIELD_TYPES.BYTE:
@@ -235,7 +236,11 @@ export const PivotPreview: FC = React.memo(
return null;
}
- if (previewMappings.properties[columnId].type === ES_FIELD_TYPES.DATE) {
+ if (
+ [ES_FIELD_TYPES.DATE, ES_FIELD_TYPES.DATE_NANOS].includes(
+ previewMappings.properties[columnId].type
+ )
+ ) {
return formatHumanReadableDateTimeSeconds(moment(cellValue).unix() * 1000);
}
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/source_index_preview/source_index_preview.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/source_index_preview/source_index_preview.tsx
index 2a467ba4a577..06ae4c81efa1 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/source_index_preview/source_index_preview.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/source_index_preview/source_index_preview.tsx
@@ -22,6 +22,8 @@ import {
EuiTitle,
} from '@elastic/eui';
+import { KBN_FIELD_TYPES } from '../../../../../../../../../src/plugins/data/common';
+
import { formatHumanReadableDateTimeSeconds } from '../../../../../../common/utils/date_utils';
import { getNestedProperty } from '../../../../../../common/utils/object_utils';
@@ -97,13 +99,14 @@ export const SourceIndexPreview: React.FC = React.memo(({ indexPattern, q
let schema;
switch (field?.type) {
- case 'date':
+ case KBN_FIELD_TYPES.DATE:
schema = 'datetime';
break;
- case 'geo_point':
+ case KBN_FIELD_TYPES.GEO_POINT:
+ case KBN_FIELD_TYPES.GEO_SHAPE:
schema = 'json';
break;
- case 'number':
+ case KBN_FIELD_TYPES.NUMBER:
schema = 'numeric';
break;
}
@@ -177,7 +180,7 @@ export const SourceIndexPreview: React.FC = React.memo(({ indexPattern, q
}
const field = indexPattern.fields.getByName(columnId);
- if (field?.type === 'date') {
+ if (field?.type === KBN_FIELD_TYPES.DATE) {
return formatHumanReadableDateTimeSeconds(moment(cellValue).unix() * 1000);
}
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
index e56a519f8080..d47af4721485 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
@@ -10,6 +10,8 @@ import { i18n } from '@kbn/i18n';
import { EuiLink, EuiSwitch, EuiFieldText, EuiForm, EuiFormRow, EuiSelect } from '@elastic/eui';
+import { KBN_FIELD_TYPES } from '../../../../../../../../../src/plugins/data/common';
+
import { toMountPoint } from '../../../../../../../../../src/plugins/kibana_react/public';
import { TransformId } from '../../../../../../common';
import { isValidIndexName } from '../../../../../../common/utils/es_utils';
@@ -148,7 +150,7 @@ export const StepDetailsForm: FC = React.memo(
}, []);
const dateFieldNames = searchItems.indexPattern.fields
- .filter(f => f.type === 'date')
+ .filter(f => f.type === KBN_FIELD_TYPES.DATE)
.map(f => f.name)
.sort();
const isContinuousModeAvailable = dateFieldNames.length > 0;
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index f2ea8f8c6dd0..aea6e2ab0009 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -1060,16 +1060,9 @@
"kbn.discover.fetchError.managmentLinkText": "管理 > インデックスパターン",
"kbn.discover.fetchError.scriptedFieldsText": "「スクリプトフィールド」",
"kbn.discover.fieldChooser.detailViews.emptyStringText": "空の文字列",
- "kbn.discover.fieldChooser.detailViews.filterOutValueButtonAriaLabel": "この値を除外",
- "kbn.discover.fieldChooser.detailViews.filterValueButtonAriaLabel": "この値でフィルターを適用",
"kbn.discover.fieldChooser.detailViews.recordsText": "記録",
"kbn.discover.fieldChooser.detailViews.topValuesInRecordsDescription": "次の記録のトップ 5 の値",
"kbn.discover.fieldChooser.detailViews.visualizeLinkText": "可視化",
- "kbn.discover.fieldChooser.detailViews.warningsText": "{warningsLength, plural, one {# 警告} other {# 警告}}",
- "kbn.discover.fieldChooser.discoverField.addButtonLabel": "追加",
- "kbn.discover.fieldChooser.discoverField.bucketAriaLabel": "値: {value}",
- "kbn.discover.fieldChooser.discoverField.emptyStringText": "空の文字列",
- "kbn.discover.fieldChooser.discoverField.removeButtonLabel": "削除",
"kbn.discover.fieldChooser.discoverField.scriptedFieldsTakeLongExecuteDescription": "スクリプトフィールドは実行に時間がかかる場合があります。",
"kbn.discover.fieldChooser.fieldCalculator.analysisIsNotAvailableForGeoFieldsErrorMessage": "ジオフィールドは分析できません。",
"kbn.discover.fieldChooser.fieldCalculator.analysisIsNotAvailableForObjectFieldsErrorMessage": "オブジェクトフィールドは分析できません。",
@@ -5783,14 +5776,10 @@
"xpack.grokDebugger.customPatternsButtonLabel": "カスタムパターン",
"xpack.grokDebugger.displayName": "Grok デバッガー",
"xpack.grokDebugger.grokPatternLabel": "Grok パターン",
- "xpack.grokDebugger.licenseHasExpiredMessage": "{licenseType} ライセンスが期限切れのため {grokLogParsingTool} デバッガーを使用できません",
"xpack.grokDebugger.patternsErrorMessage": "提供された {grokLogParsingTool} パターンがインプットのデータと一致していません",
- "xpack.grokDebugger.registryProviderDescription": "{grokLogParsingTool} パターンを、投入時にデータ変換用にシミュレートしデバッグします。",
- "xpack.grokDebugger.registryProviderTitle": "{grokLogParsingTool} デバッガー",
"xpack.grokDebugger.sampleDataLabel": "サンプルデータ",
"xpack.grokDebugger.simulateButtonLabel": "シミュレート",
"xpack.grokDebugger.structuredDataLabel": "構造化データ",
- "xpack.grokDebugger.unavailableLicenseInformationMessage": "現在ライセンス情報が利用できないため {grokLogParsingTool} デバッガーを使用できません。",
"xpack.idxMgmt.appTitle": "インデックス管理",
"xpack.idxMgmt.badgeAriaLabel": "{label}。これをフィルタリングするよう選択。",
"xpack.idxMgmt.breadcrumb.cloneTemplateLabel": "テンプレートのクローンを作成",
@@ -6303,7 +6292,6 @@
"xpack.infra.logEntryActionsMenu.apmActionLabel": "APMで表示",
"xpack.infra.logEntryActionsMenu.buttonLabel": "アクション",
"xpack.infra.logEntryActionsMenu.uptimeActionLabel": "監視ステータスを表示",
- "xpack.infra.logEntryItemView.viewDetailsToolTip": "詳細を表示",
"xpack.infra.logFlyout.fieldColumnLabel": "フィールド",
"xpack.infra.logFlyout.filterAriaLabel": "フィルター",
"xpack.infra.logFlyout.flyoutTitle": "ログイベントドキュメントの詳細",
@@ -7420,7 +7408,6 @@
"xpack.ml.calendarsEdit.newEventModal.startDateAriaLabel": "開始日",
"xpack.ml.calendarsEdit.newEventModal.toLabel": "終了:",
"xpack.ml.calendarsList.deleteCalendars.calendarsLabel": "{calendarsToDeleteCount} 件のカレンダー",
- "xpack.ml.calendarsList.deleteCalendars.deletingCalendarErrorMessage": "カレンダー {calendarId} の削除中にエラーが発生しました: {errorMessage}",
"xpack.ml.calendarsList.deleteCalendars.deletingCalendarsNotificationMessage": "{messageId} を削除中",
"xpack.ml.calendarsList.deleteCalendars.deletingCalendarSuccessNotificationMessage": "{messageId} が選択されました",
"xpack.ml.calendarsList.deleteCalendarsModal.cancelButtonLabel": "キャンセル",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 0dd584e32a24..dfc5ef065732 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -1060,16 +1060,9 @@
"kbn.discover.fetchError.managmentLinkText": "管理 > 索引模式",
"kbn.discover.fetchError.scriptedFieldsText": "“脚本字段”",
"kbn.discover.fieldChooser.detailViews.emptyStringText": "空字符串",
- "kbn.discover.fieldChooser.detailViews.filterOutValueButtonAriaLabel": "筛除此值",
- "kbn.discover.fieldChooser.detailViews.filterValueButtonAriaLabel": "筛留此值",
"kbn.discover.fieldChooser.detailViews.recordsText": "个记录",
"kbn.discover.fieldChooser.detailViews.topValuesInRecordsDescription": "排名前 5 位的值,范围:",
"kbn.discover.fieldChooser.detailViews.visualizeLinkText": "可视化",
- "kbn.discover.fieldChooser.detailViews.warningsText": "{warningsLength, plural, one {# 个警告} other {# 个警告}}",
- "kbn.discover.fieldChooser.discoverField.addButtonLabel": "添加",
- "kbn.discover.fieldChooser.discoverField.bucketAriaLabel": "值:{value}",
- "kbn.discover.fieldChooser.discoverField.emptyStringText": "空字符串",
- "kbn.discover.fieldChooser.discoverField.removeButtonLabel": "移除",
"kbn.discover.fieldChooser.discoverField.scriptedFieldsTakeLongExecuteDescription": "脚本字段执行时间会很长。",
"kbn.discover.fieldChooser.fieldCalculator.analysisIsNotAvailableForGeoFieldsErrorMessage": "分析不适用于地理字段。",
"kbn.discover.fieldChooser.fieldCalculator.analysisIsNotAvailableForObjectFieldsErrorMessage": "分析不适用于对象字段。",
@@ -5783,14 +5776,10 @@
"xpack.grokDebugger.customPatternsButtonLabel": "自定义模式",
"xpack.grokDebugger.displayName": "Grok Debugger",
"xpack.grokDebugger.grokPatternLabel": "Grok 模式",
- "xpack.grokDebugger.licenseHasExpiredMessage": "您不能使用 {grokLogParsingTool} Debugger,因为您的 {licenseType} 许可证已过期。",
"xpack.grokDebugger.patternsErrorMessage": "提供的 {grokLogParsingTool} 模式不匹配输入中的数据",
- "xpack.grokDebugger.registryProviderDescription": "采集时模拟和调试用于数据转换的 {grokLogParsingTool} 模式。",
- "xpack.grokDebugger.registryProviderTitle": "{grokLogParsingTool} Debugger",
"xpack.grokDebugger.sampleDataLabel": "样例数据",
"xpack.grokDebugger.simulateButtonLabel": "模拟",
"xpack.grokDebugger.structuredDataLabel": "结构化数据",
- "xpack.grokDebugger.unavailableLicenseInformationMessage": "您不能使用 {grokLogParsingTool} Debugger,因为许可证信息当前不可用。",
"xpack.idxMgmt.appTitle": "索引管理",
"xpack.idxMgmt.badgeAriaLabel": "{label}。选择以基于此选项进行筛选。",
"xpack.idxMgmt.breadcrumb.cloneTemplateLabel": "克隆模板",
@@ -6303,7 +6292,6 @@
"xpack.infra.logEntryActionsMenu.apmActionLabel": "在 APM 中查看",
"xpack.infra.logEntryActionsMenu.buttonLabel": "操作",
"xpack.infra.logEntryActionsMenu.uptimeActionLabel": "查看监测状态",
- "xpack.infra.logEntryItemView.viewDetailsToolTip": "查看详情",
"xpack.infra.logFlyout.fieldColumnLabel": "字段",
"xpack.infra.logFlyout.filterAriaLabel": "筛选",
"xpack.infra.logFlyout.flyoutTitle": "日志事件文档详情",
@@ -7420,7 +7408,6 @@
"xpack.ml.calendarsEdit.newEventModal.startDateAriaLabel": "开始日期",
"xpack.ml.calendarsEdit.newEventModal.toLabel": "到:",
"xpack.ml.calendarsList.deleteCalendars.calendarsLabel": "{calendarsToDeleteCount} 个日历",
- "xpack.ml.calendarsList.deleteCalendars.deletingCalendarErrorMessage": "删除日历 {calendarId} 时出错。{errorMessage}",
"xpack.ml.calendarsList.deleteCalendars.deletingCalendarsNotificationMessage": "正在删除 {messageId}",
"xpack.ml.calendarsList.deleteCalendars.deletingCalendarSuccessNotificationMessage": "已删除 {messageId}",
"xpack.ml.calendarsList.deleteCalendarsModal.cancelButtonLabel": "取消",
diff --git a/x-pack/plugins/triggers_actions_ui/public/common/expression_items/of.scss b/x-pack/plugins/triggers_actions_ui/public/common/expression_items/of.scss
new file mode 100644
index 000000000000..6b55a43201d1
--- /dev/null
+++ b/x-pack/plugins/triggers_actions_ui/public/common/expression_items/of.scss
@@ -0,0 +1,3 @@
+.actOf__aggFieldContainer {
+ width: $euiSize * 29;
+}
diff --git a/x-pack/plugins/triggers_actions_ui/public/common/expression_items/of.tsx b/x-pack/plugins/triggers_actions_ui/public/common/expression_items/of.tsx
index 70aa4be6b7f8..d399f6136690 100644
--- a/x-pack/plugins/triggers_actions_ui/public/common/expression_items/of.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/common/expression_items/of.tsx
@@ -18,6 +18,7 @@ import {
import { builtInAggregationTypes } from '../constants';
import { AggregationType } from '../types';
import { ClosablePopoverTitle } from './components';
+import './of.scss';
interface OfExpressionProps {
aggType: string;
@@ -108,7 +109,7 @@ export const OfExpression = ({
/>
-
+
0 && aggField !== undefined}
diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/op_utils.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/op_utils.ts
index ecba02e0d546..7e921d8c571d 100644
--- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/op_utils.ts
+++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/op_utils.ts
@@ -50,6 +50,9 @@ const orderQueuedReindexOperations = ({
),
});
+export const isQueuedOp = (op: ReindexSavedObject) =>
+ Boolean(op.attributes.reindexOptions?.queueSettings);
+
export const queuedOpHasStarted = (op: ReindexSavedObject) =>
Boolean(op.attributes.reindexOptions?.queueSettings?.startedAt);
diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts
index d6051ce46312..8aa678b2f66c 100644
--- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts
+++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts
@@ -10,12 +10,18 @@ import { Credential, CredentialStore } from './credential_store';
import { reindexActionsFactory } from './reindex_actions';
import { ReindexService, reindexServiceFactory } from './reindex_service';
import { LicensingPluginSetup } from '../../../../licensing/server';
-import { sortAndOrderReindexOperations, queuedOpHasStarted } from './op_utils';
+import { sortAndOrderReindexOperations, queuedOpHasStarted, isQueuedOp } from './op_utils';
const POLL_INTERVAL = 30000;
// If no nodes have been able to update this index in 2 minutes (due to missing credentials), set to paused.
const PAUSE_WINDOW = POLL_INTERVAL * 4;
+/**
+ * To avoid running the worker loop very tightly and causing a CPU bottleneck we use this
+ * padding to simulate an asynchronous sleep. See the description of the tight loop below.
+ */
+const WORKER_PADDING_MS = 1000;
+
/**
* A singleton worker that will coordinate two polling loops:
* (1) A longer loop that polls for reindex operations that are in progress. If any are found, loop (2) is started.
@@ -102,16 +108,25 @@ export class ReindexWorker {
/**
* Runs an async loop until all inProgress jobs are complete or failed.
*/
- private startUpdateOperationLoop = async () => {
+ private startUpdateOperationLoop = async (): Promise => {
this.updateOperationLoopRunning = true;
-
try {
while (this.inProgressOps.length > 0) {
this.log.debug(`Updating ${this.inProgressOps.length} reindex operations`);
// Push each operation through the state machine and refresh.
await Promise.all(this.inProgressOps.map(this.processNextStep));
+
await this.refresh();
+
+ if (
+ this.inProgressOps.length &&
+ this.inProgressOps.every(op => !this.credentialStore.get(op))
+ ) {
+ // TODO: This tight loop needs something to relax potentially high CPU demands so this padding is added.
+ // This scheduler should be revisited in future.
+ await new Promise(resolve => setTimeout(resolve, WORKER_PADDING_MS));
+ }
}
} finally {
this.updateOperationLoopRunning = false;
@@ -173,20 +188,32 @@ export class ReindexWorker {
}
};
- private processNextStep = async (reindexOp: ReindexSavedObject) => {
+ private lastCheckedQueuedOpId: string | undefined;
+ private processNextStep = async (reindexOp: ReindexSavedObject): Promise => {
const credential = this.credentialStore.get(reindexOp);
if (!credential) {
- // Set to paused state if the job hasn't been updated in PAUSE_WINDOW.
+ // If this is a queued reindex op, and we know there can only ever be one in progress at a
+ // given time, there is a small chance it may have just reached the front of the queue so
+ // we give it a chance to be updated by another worker with credentials by making this a
+ // noop once. If it has not been updated by the next loop we will mark it paused if it
+ // falls outside of PAUSE_WINDOW.
+ if (isQueuedOp(reindexOp)) {
+ if (this.lastCheckedQueuedOpId !== reindexOp.id) {
+ this.lastCheckedQueuedOpId = reindexOp.id;
+ return;
+ }
+ }
// This indicates that no Kibana nodes currently have credentials to update this job.
const now = moment();
const updatedAt = moment(reindexOp.updated_at);
if (updatedAt < now.subtract(PAUSE_WINDOW)) {
- return this.reindexService.pauseReindexOperation(reindexOp.attributes.indexName);
+ await this.reindexService.pauseReindexOperation(reindexOp.attributes.indexName);
+ return;
} else {
// If it has been updated recently, we assume another node has the necessary credentials,
// and this becomes a noop.
- return reindexOp;
+ return;
}
}
diff --git a/x-pack/test/api_integration/apis/ml/bucket_span_estimator.ts b/x-pack/test/api_integration/apis/ml/bucket_span_estimator.ts
index a50d65a48c2b..3f56fb927d13 100644
--- a/x-pack/test/api_integration/apis/ml/bucket_span_estimator.ts
+++ b/x-pack/test/api_integration/apis/ml/bucket_span_estimator.ts
@@ -18,7 +18,7 @@ export default ({ getService }: FtrProviderContext) => {
const esArchiver = getService('esArchiver');
const esSupertest = getService('esSupertest');
const supertest = getService('supertestWithoutAuth');
- const mlSecurity = getService('mlSecurity');
+ const ml = getService('ml');
const testDataList = [
{
@@ -103,7 +103,7 @@ export default ({ getService }: FtrProviderContext) => {
it(`estimates the bucket span ${testData.testTitleSuffix}`, async () => {
const { body } = await supertest
.post('/api/ml/validate/estimate_bucket_span')
- .auth(testData.user, mlSecurity.getPasswordForUser(testData.user))
+ .auth(testData.user, ml.securityCommon.getPasswordForUser(testData.user))
.set(COMMON_HEADERS)
.send(testData.requestBody)
.expect(testData.expected.responseCode);
@@ -133,7 +133,7 @@ export default ({ getService }: FtrProviderContext) => {
it(`estimates the bucket span`, async () => {
const { body } = await supertest
.post('/api/ml/validate/estimate_bucket_span')
- .auth(testData.user, mlSecurity.getPasswordForUser(testData.user))
+ .auth(testData.user, ml.securityCommon.getPasswordForUser(testData.user))
.set(COMMON_HEADERS)
.send(testData.requestBody)
.expect(testData.expected.responseCode);
@@ -162,7 +162,7 @@ export default ({ getService }: FtrProviderContext) => {
it(`estimates the bucket span`, async () => {
const { body } = await supertest
.post('/api/ml/validate/estimate_bucket_span')
- .auth(testData.user, mlSecurity.getPasswordForUser(testData.user))
+ .auth(testData.user, ml.securityCommon.getPasswordForUser(testData.user))
.set(COMMON_HEADERS)
.send(testData.requestBody)
.expect(testData.expected.responseCode);
diff --git a/x-pack/test/api_integration/apis/ml/calculate_model_memory_limit.ts b/x-pack/test/api_integration/apis/ml/calculate_model_memory_limit.ts
index 7fb0a10d94a4..c36621a9a640 100644
--- a/x-pack/test/api_integration/apis/ml/calculate_model_memory_limit.ts
+++ b/x-pack/test/api_integration/apis/ml/calculate_model_memory_limit.ts
@@ -15,7 +15,7 @@ const COMMON_HEADERS = {
export default ({ getService }: FtrProviderContext) => {
const esArchiver = getService('esArchiver');
const supertest = getService('supertestWithoutAuth');
- const mlSecurity = getService('mlSecurity');
+ const ml = getService('ml');
const testDataList = [
{
@@ -158,7 +158,7 @@ export default ({ getService }: FtrProviderContext) => {
it(`calculates the model memory limit ${testData.testTitleSuffix}`, async () => {
await supertest
.post('/api/ml/validate/calculate_model_memory_limit')
- .auth(testData.user, mlSecurity.getPasswordForUser(testData.user))
+ .auth(testData.user, ml.securityCommon.getPasswordForUser(testData.user))
.set(COMMON_HEADERS)
.send(testData.requestBody)
.expect(testData.expected.responseCode);
diff --git a/x-pack/test/api_integration/apis/ml/categorization_field_examples.ts b/x-pack/test/api_integration/apis/ml/categorization_field_examples.ts
index aab7a65a7c12..b8ee2e7f6562 100644
--- a/x-pack/test/api_integration/apis/ml/categorization_field_examples.ts
+++ b/x-pack/test/api_integration/apis/ml/categorization_field_examples.ts
@@ -79,7 +79,7 @@ const defaultRequestBody = {
export default ({ getService }: FtrProviderContext) => {
const esArchiver = getService('esArchiver');
const supertest = getService('supertestWithoutAuth');
- const mlSecurity = getService('mlSecurity');
+ const ml = getService('ml');
const testDataList = [
{
@@ -300,7 +300,7 @@ export default ({ getService }: FtrProviderContext) => {
it(testData.title, async () => {
const { body } = await supertest
.post('/api/ml/jobs/categorization_field_examples')
- .auth(testData.user, mlSecurity.getPasswordForUser(testData.user))
+ .auth(testData.user, ml.securityCommon.getPasswordForUser(testData.user))
.set(COMMON_HEADERS)
.send(testData.requestBody)
.expect(testData.expected.responseCode);
diff --git a/x-pack/test/api_integration/apis/ml/get_module.ts b/x-pack/test/api_integration/apis/ml/get_module.ts
index 4478236c494a..6dcd9594fc9a 100644
--- a/x-pack/test/api_integration/apis/ml/get_module.ts
+++ b/x-pack/test/api_integration/apis/ml/get_module.ts
@@ -37,12 +37,12 @@ const moduleIds = [
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertestWithoutAuth');
- const mlSecurity = getService('mlSecurity');
+ const ml = getService('ml');
async function executeGetModuleRequest(module: string, user: USER, rspCode: number) {
const { body } = await supertest
.get(`/api/ml/modules/get_module/${module}`)
- .auth(user, mlSecurity.getPasswordForUser(user))
+ .auth(user, ml.securityCommon.getPasswordForUser(user))
.set(COMMON_HEADERS)
.expect(rspCode);
diff --git a/x-pack/test/api_integration/apis/ml/index.ts b/x-pack/test/api_integration/apis/ml/index.ts
index 78f99d8d9776..4e21faa610bf 100644
--- a/x-pack/test/api_integration/apis/ml/index.ts
+++ b/x-pack/test/api_integration/apis/ml/index.ts
@@ -7,24 +7,26 @@
import { FtrProviderContext } from '../../ftr_provider_context';
export default function({ getService, loadTestFile }: FtrProviderContext) {
- const mlSecurity = getService('mlSecurity');
+ const ml = getService('ml');
describe('Machine Learning', function() {
this.tags(['mlqa']);
before(async () => {
- await mlSecurity.createMlRoles();
- await mlSecurity.createMlUsers();
+ await ml.securityCommon.createMlRoles();
+ await ml.securityCommon.createMlUsers();
});
after(async () => {
- await mlSecurity.cleanMlUsers();
- await mlSecurity.cleanMlRoles();
+ await ml.securityCommon.cleanMlUsers();
+ await ml.securityCommon.cleanMlRoles();
});
loadTestFile(require.resolve('./bucket_span_estimator'));
loadTestFile(require.resolve('./calculate_model_memory_limit'));
loadTestFile(require.resolve('./categorization_field_examples'));
loadTestFile(require.resolve('./get_module'));
+ loadTestFile(require.resolve('./recognize_module'));
+ loadTestFile(require.resolve('./setup_module'));
});
}
diff --git a/x-pack/test/api_integration/apis/ml/recognize_module.ts b/x-pack/test/api_integration/apis/ml/recognize_module.ts
new file mode 100644
index 000000000000..2110bded7394
--- /dev/null
+++ b/x-pack/test/api_integration/apis/ml/recognize_module.ts
@@ -0,0 +1,80 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import expect from '@kbn/expect';
+
+import { FtrProviderContext } from '../../ftr_provider_context';
+import { USER } from '../../../functional/services/machine_learning/security_common';
+
+const COMMON_HEADERS = {
+ 'kbn-xsrf': 'some-xsrf-token',
+};
+
+// eslint-disable-next-line import/no-default-export
+export default ({ getService }: FtrProviderContext) => {
+ const esArchiver = getService('esArchiver');
+ const supertest = getService('supertestWithoutAuth');
+ const ml = getService('ml');
+
+ const testDataList = [
+ {
+ testTitleSuffix: 'for sample logs dataset',
+ sourceDataArchive: 'ml/sample_logs',
+ indexPattern: 'kibana_sample_data_logs',
+ user: USER.ML_POWERUSER,
+ expected: {
+ responseCode: 200,
+ moduleIds: ['sample_data_weblogs'],
+ },
+ },
+ {
+ testTitleSuffix: 'for non existent index pattern',
+ sourceDataArchive: 'empty_kibana',
+ indexPattern: 'non-existent-index-pattern',
+ user: USER.ML_POWERUSER,
+ expected: {
+ responseCode: 200,
+ moduleIds: [],
+ },
+ },
+ ];
+
+ async function executeRecognizeModuleRequest(indexPattern: string, user: USER, rspCode: number) {
+ const { body } = await supertest
+ .get(`/api/ml/modules/recognize/${indexPattern}`)
+ .auth(user, ml.securityCommon.getPasswordForUser(user))
+ .set(COMMON_HEADERS)
+ .expect(rspCode);
+
+ return body;
+ }
+
+ describe('module recognizer', function() {
+ for (const testData of testDataList) {
+ describe('lists matching modules', function() {
+ before(async () => {
+ await esArchiver.load(testData.sourceDataArchive);
+ });
+
+ after(async () => {
+ await esArchiver.unload(testData.sourceDataArchive);
+ });
+
+ it(testData.testTitleSuffix, async () => {
+ const rspBody = await executeRecognizeModuleRequest(
+ testData.indexPattern,
+ testData.user,
+ testData.expected.responseCode
+ );
+ expect(rspBody).to.be.an(Array);
+
+ const responseModuleIds = rspBody.map((module: { id: string }) => module.id);
+ expect(responseModuleIds).to.eql(testData.expected.moduleIds);
+ });
+ });
+ }
+ });
+};
diff --git a/x-pack/test/api_integration/apis/ml/setup_module.ts b/x-pack/test/api_integration/apis/ml/setup_module.ts
new file mode 100644
index 000000000000..71f3910cd4e9
--- /dev/null
+++ b/x-pack/test/api_integration/apis/ml/setup_module.ts
@@ -0,0 +1,229 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import expect from '@kbn/expect';
+
+import { FtrProviderContext } from '../../ftr_provider_context';
+
+import { JOB_STATE, DATAFEED_STATE } from '../../../../plugins/ml/common/constants/states';
+import { USER } from '../../../functional/services/machine_learning/security_common';
+
+const COMMON_HEADERS = {
+ 'kbn-xsrf': 'some-xsrf-token',
+};
+
+// eslint-disable-next-line import/no-default-export
+export default ({ getService }: FtrProviderContext) => {
+ const esArchiver = getService('esArchiver');
+ const supertest = getService('supertestWithoutAuth');
+ const ml = getService('ml');
+
+ const testDataListPositive = [
+ {
+ testTitleSuffix: 'for sample logs dataset with prefix and startDatafeed false',
+ sourceDataArchive: 'ml/sample_logs',
+ module: 'sample_data_weblogs',
+ user: USER.ML_POWERUSER,
+ requestBody: {
+ prefix: 'pf1_',
+ indexPatternName: 'kibana_sample_data_logs',
+ startDatafeed: false,
+ },
+ expected: {
+ responseCode: 200,
+ jobs: [
+ {
+ jobId: 'pf1_low_request_rate',
+ jobState: JOB_STATE.CLOSED,
+ datafeedState: DATAFEED_STATE.STOPPED,
+ },
+ {
+ jobId: 'pf1_response_code_rates',
+ jobState: JOB_STATE.CLOSED,
+ datafeedState: DATAFEED_STATE.STOPPED,
+ },
+ {
+ jobId: 'pf1_url_scanning',
+ jobState: JOB_STATE.CLOSED,
+ datafeedState: DATAFEED_STATE.STOPPED,
+ },
+ ],
+ },
+ },
+ ];
+
+ const testDataListNegative = [
+ {
+ testTitleSuffix: 'for non existent index pattern',
+ sourceDataArchive: 'empty_kibana',
+ module: 'sample_data_weblogs',
+ user: USER.ML_POWERUSER,
+ requestBody: {
+ indexPatternName: 'non-existent-index-pattern',
+ startDatafeed: false,
+ },
+ expected: {
+ responseCode: 400,
+ error: 'Bad Request',
+ message:
+ "Module's jobs contain custom URLs which require a kibana index pattern (non-existent-index-pattern) which cannot be found.",
+ },
+ },
+ {
+ testTitleSuffix: 'for unauthorized user',
+ sourceDataArchive: 'ml/sample_logs',
+ module: 'sample_data_weblogs',
+ user: USER.ML_UNAUTHORIZED,
+ requestBody: {
+ prefix: 'pf1_',
+ indexPatternName: 'kibana_sample_data_logs',
+ startDatafeed: false,
+ },
+ expected: {
+ responseCode: 403,
+ error: 'Forbidden',
+ message:
+ '[security_exception] action [cluster:monitor/xpack/ml/info/get] is unauthorized for user [ml_unauthorized]',
+ },
+ },
+ ];
+
+ async function executeSetupModuleRequest(
+ module: string,
+ user: USER,
+ rqBody: object,
+ rspCode: number
+ ) {
+ const { body } = await supertest
+ .post(`/api/ml/modules/setup/${module}`)
+ .auth(user, ml.securityCommon.getPasswordForUser(user))
+ .set(COMMON_HEADERS)
+ .send(rqBody)
+ .expect(rspCode);
+
+ return body;
+ }
+
+ function compareById(a: { id: string }, b: { id: string }) {
+ if (a.id < b.id) {
+ return -1;
+ }
+ if (a.id > b.id) {
+ return 1;
+ }
+ return 0;
+ }
+
+ describe('module setup', function() {
+ for (const testData of testDataListPositive) {
+ describe('sets up module data', function() {
+ before(async () => {
+ await esArchiver.load(testData.sourceDataArchive);
+ });
+
+ after(async () => {
+ await esArchiver.unload(testData.sourceDataArchive);
+ await ml.api.cleanMlIndices();
+ });
+
+ it(testData.testTitleSuffix, async () => {
+ const rspBody = await executeSetupModuleRequest(
+ testData.module,
+ testData.user,
+ testData.requestBody,
+ testData.expected.responseCode
+ );
+
+ // verify response
+ if (testData.expected.jobs.length > 0) {
+ // jobs
+ expect(rspBody).to.have.property('jobs');
+
+ const expectedRspJobs = testData.expected.jobs
+ .map(job => {
+ return { id: job.jobId, success: true };
+ })
+ .sort(compareById);
+
+ const actualRspJobs = rspBody.jobs.sort(compareById);
+
+ expect(actualRspJobs).to.eql(
+ expectedRspJobs,
+ `Expected setup module response jobs to be '${JSON.stringify(
+ expectedRspJobs
+ )}' (got '${JSON.stringify(actualRspJobs)}')`
+ );
+
+ // datafeeds
+ expect(rspBody).to.have.property('datafeeds');
+
+ const expectedRspDatafeeds = testData.expected.jobs
+ .map(job => {
+ return {
+ id: `datafeed-${job.jobId}`,
+ success: true,
+ started: testData.requestBody.startDatafeed,
+ };
+ })
+ .sort(compareById);
+
+ const actualRspDatafeeds = rspBody.datafeeds.sort(compareById);
+
+ expect(actualRspDatafeeds).to.eql(
+ expectedRspDatafeeds,
+ `Expected setup module response datafeeds to be '${JSON.stringify(
+ expectedRspDatafeeds
+ )}' (got '${JSON.stringify(actualRspDatafeeds)}')`
+ );
+
+ // TODO in future updates: add response validations for created saved objects
+ }
+
+ // verify job and datafeed creation + states
+ for (const job of testData.expected.jobs) {
+ const datafeedId = `datafeed-${job.jobId}`;
+ await ml.api.waitForAnomalyDetectionJobToExist(job.jobId);
+ await ml.api.waitForDatafeedToExist(datafeedId);
+ await ml.api.waitForJobState(job.jobId, job.jobState);
+ await ml.api.waitForDatafeedState(datafeedId, job.datafeedState);
+ }
+ });
+
+ // TODO in future updates: add creation validations for created saved objects
+ });
+ }
+
+ for (const testData of testDataListNegative) {
+ describe('rejects request', function() {
+ before(async () => {
+ await esArchiver.load(testData.sourceDataArchive);
+ });
+
+ after(async () => {
+ await esArchiver.unload(testData.sourceDataArchive);
+ await ml.api.cleanMlIndices();
+ });
+
+ it(testData.testTitleSuffix, async () => {
+ const rspBody = await executeSetupModuleRequest(
+ testData.module,
+ testData.user,
+ testData.requestBody,
+ testData.expected.responseCode
+ );
+
+ expect(rspBody)
+ .to.have.property('error')
+ .eql(testData.expected.error);
+
+ expect(rspBody)
+ .to.have.property('message')
+ .eql(testData.expected.message);
+ });
+ });
+ }
+ });
+};
diff --git a/x-pack/test/api_integration/services/index.ts b/x-pack/test/api_integration/services/index.ts
index c29116e1270c..9c945f557a2d 100644
--- a/x-pack/test/api_integration/services/index.ts
+++ b/x-pack/test/api_integration/services/index.ts
@@ -21,7 +21,7 @@ import {
} from './infraops_graphql_client';
import { SiemGraphQLClientProvider, SiemGraphQLClientFactoryProvider } from './siem_graphql_client';
import { InfraOpsSourceConfigurationProvider } from './infraops_source_configuration';
-import { MachineLearningSecurityCommonProvider } from '../../functional/services/machine_learning';
+import { MachineLearningProvider } from './ml';
export const services = {
...commonServices,
@@ -38,5 +38,5 @@ export const services = {
siemGraphQLClientFactory: SiemGraphQLClientFactoryProvider,
supertestWithoutAuth: SupertestWithoutAuthProvider,
usageAPI: UsageAPIProvider,
- mlSecurity: MachineLearningSecurityCommonProvider,
+ ml: MachineLearningProvider,
};
diff --git a/x-pack/test/api_integration/services/ml.ts b/x-pack/test/api_integration/services/ml.ts
new file mode 100644
index 000000000000..841b200b8708
--- /dev/null
+++ b/x-pack/test/api_integration/services/ml.ts
@@ -0,0 +1,22 @@
+/*
+ * 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 { FtrProviderContext } from '../../functional/ftr_provider_context';
+
+import {
+ MachineLearningAPIProvider,
+ MachineLearningSecurityCommonProvider,
+} from '../../functional/services/machine_learning';
+
+export function MachineLearningProvider(context: FtrProviderContext) {
+ const api = MachineLearningAPIProvider(context);
+ const securityCommon = MachineLearningSecurityCommonProvider(context);
+
+ return {
+ api,
+ securityCommon,
+ };
+}
diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/utils.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/utils.ts
index c92e351ed591..f1404b79a07a 100644
--- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/utils.ts
+++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/utils.ts
@@ -151,6 +151,7 @@ export const getSimpleRuleOutput = (ruleId = 'rule-1'): Partial {
+ // FLAKY: https://github.com/elastic/kibana/issues/57413
+ describe.skip('spaces feature controls', () => {
before(async () => {
await esArchiver.loadIfNeeded('logstash_functional');
});
diff --git a/x-pack/test/functional/es_archives/ml/sample_logs/data.json.gz b/x-pack/test/functional/es_archives/ml/sample_logs/data.json.gz
new file mode 100644
index 000000000000..03ceb319a6af
Binary files /dev/null and b/x-pack/test/functional/es_archives/ml/sample_logs/data.json.gz differ
diff --git a/x-pack/test/functional/es_archives/ml/sample_logs/mappings.json b/x-pack/test/functional/es_archives/ml/sample_logs/mappings.json
new file mode 100644
index 000000000000..1c7490e139be
--- /dev/null
+++ b/x-pack/test/functional/es_archives/ml/sample_logs/mappings.json
@@ -0,0 +1,3162 @@
+{
+ "type": "index",
+ "value": {
+ "aliases": {
+ },
+ "index": "kibana_sample_data_logs",
+ "mappings": {
+ "properties": {
+ "@timestamp": {
+ "path": "timestamp",
+ "type": "alias"
+ },
+ "agent": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "bytes": {
+ "type": "long"
+ },
+ "clientip": {
+ "type": "ip"
+ },
+ "event": {
+ "properties": {
+ "dataset": {
+ "type": "keyword"
+ }
+ }
+ },
+ "extension": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "geo": {
+ "properties": {
+ "coordinates": {
+ "type": "geo_point"
+ },
+ "dest": {
+ "type": "keyword"
+ },
+ "src": {
+ "type": "keyword"
+ },
+ "srcdest": {
+ "type": "keyword"
+ }
+ }
+ },
+ "host": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "index": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "ip": {
+ "type": "ip"
+ },
+ "machine": {
+ "properties": {
+ "os": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "ram": {
+ "type": "long"
+ }
+ }
+ },
+ "memory": {
+ "type": "double"
+ },
+ "message": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "phpmemory": {
+ "type": "long"
+ },
+ "referer": {
+ "type": "keyword"
+ },
+ "request": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "response": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "tags": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "timestamp": {
+ "type": "date"
+ },
+ "url": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "utc_time": {
+ "type": "date"
+ }
+ }
+ },
+ "settings": {
+ "index": {
+ "auto_expand_replicas": "0-1",
+ "number_of_replicas": "0",
+ "number_of_shards": "1"
+ }
+ }
+ }
+}
+
+{
+ "type": "index",
+ "value": {
+ "aliases": {
+ ".kibana": {
+ }
+ },
+ "index": ".kibana_1",
+ "mappings": {
+ "_meta": {
+ "migrationMappingPropertyHashes": {
+ "action": "6e96ac5e648f57523879661ea72525b7",
+ "action_task_params": "a9d49f184ee89641044be0ca2950fa3a",
+ "agent_configs": "38abaf89513877745c359e7700c0c66a",
+ "agent_events": "3231653fafe4ef3196fe3b32ab774bf2",
+ "agents": "75c0f4a11560dbc38b65e5e1d98fc9da",
+ "alert": "7b44fba6773e37c806ce290ea9b7024e",
+ "apm-indices": "9bb9b2bf1fa636ed8619cbab5ce6a1dd",
+ "apm-telemetry": "e8619030e08b671291af04c4603b4944",
+ "application_usage_totals": "c897e4310c5f24b07caaff3db53ae2c1",
+ "application_usage_transactional": "965839e75f809fefe04f92dc4d99722a",
+ "canvas-element": "7390014e1091044523666d97247392fc",
+ "canvas-workpad": "b0a1706d356228dbdcb4a17e6b9eb231",
+ "cases": "08b8b110dbca273d37e8aef131ecab61",
+ "cases-comments": "c2061fb929f585df57425102fa928b4b",
+ "cases-configure": "42711cbb311976c0687853f4c1354572",
+ "cases-user-actions": "32277330ec6b721abe3b846cfd939a71",
+ "config": "ae24d22d5986d04124cc6568f771066f",
+ "dashboard": "d00f614b29a80360e1190193fd333bab",
+ "datasources": "d4bc0c252b2b5683ff21ea32d00acffc",
+ "enrollment_api_keys": "28b91e20b105b6f928e2012600085d8f",
+ "epm-package": "75d12cd13c867fd713d7dfb27366bc20",
+ "file-upload-telemetry": "0ed4d3e1983d1217a30982630897092e",
+ "graph-workspace": "cd7ba1330e6682e9cc00b78850874be1",
+ "index-pattern": "66eccb05066c5a89924f48a9e9736499",
+ "infrastructure-ui-source": "ddc0ecb18383f6b26101a2fadb2dab0c",
+ "inventory-view": "9ecce5b58867403613d82fe496470b34",
+ "kql-telemetry": "d12a98a6f19a2d273696597547e064ee",
+ "lens": "21c3ea0763beb1ecb0162529706b88c5",
+ "lens-ui-telemetry": "509bfa5978586998e05f9e303c07a327",
+ "map": "23d7aa4a720d4938ccde3983f87bd58d",
+ "maps-telemetry": "268da3a48066123fc5baf35abaa55014",
+ "metrics-explorer-view": "53c5365793677328df0ccb6138bf3cdd",
+ "migrationVersion": "4a1746014a75ade3a714e1db5763276f",
+ "ml-telemetry": "257fd1d4b4fdbb9cb4b8a3b27da201e9",
+ "namespace": "2f4316de49999235636386fe51dc06c1",
+ "outputs": "aee9782e0d500b867859650a36280165",
+ "query": "11aaeb7f5f7fa5bb43f25e18ce26e7d9",
+ "references": "7997cf5a56cc02bdc9c93361bde732b0",
+ "sample-data-telemetry": "7d3cfeb915303c9641c59681967ffeb4",
+ "search": "181661168bbadd1eff5902361e2a0d5c",
+ "server": "ec97f1c5da1a19609a60874e5af1100c",
+ "siem-detection-engine-rule-status": "ae783f41c6937db6b7a2ef5c93a9e9b0",
+ "siem-ui-timeline": "ac8020190f5950dd3250b6499144e7fb",
+ "siem-ui-timeline-note": "8874706eedc49059d4cf0f5094559084",
+ "siem-ui-timeline-pinned-event": "20638091112f0e14f0e443d512301c29",
+ "space": "c5ca8acafa0beaa4d08d014a97b6bc6b",
+ "telemetry": "36a616f7026dfa617d6655df850fe16d",
+ "timelion-sheet": "9a2a2748877c7a7b582fef201ab1d4cf",
+ "tsvb-validation-telemetry": "3a37ef6c8700ae6fc97d5c7da00e9215",
+ "type": "2f4316de49999235636386fe51dc06c1",
+ "ui-metric": "0d409297dc5ebe1e3a1da691c6ee32e3",
+ "updated_at": "00da57df13e94e9d98437d13ace4bfe0",
+ "upgrade-assistant-reindex-operation": "a53a20fe086b72c9a86da3cc12dad8a6",
+ "upgrade-assistant-telemetry": "56702cec857e0a9dacfb696655b4ff7b",
+ "uptime-dynamic-settings": "b6289473c8985c79b6c47eebc19a0ca5",
+ "url": "c7f66a0df8b1b52f17c28c4adb111105",
+ "visualization": "52d7a13ad68a150c4525b292d23e12cc"
+ }
+ },
+ "dynamic": "strict",
+ "properties": {
+ "action": {
+ "properties": {
+ "actionTypeId": {
+ "type": "keyword"
+ },
+ "config": {
+ "enabled": false,
+ "type": "object"
+ },
+ "name": {
+ "fields": {
+ "keyword": {
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "secrets": {
+ "type": "binary"
+ }
+ }
+ },
+ "action_task_params": {
+ "properties": {
+ "actionId": {
+ "type": "keyword"
+ },
+ "apiKey": {
+ "type": "binary"
+ },
+ "params": {
+ "enabled": false,
+ "type": "object"
+ }
+ }
+ },
+ "agent_configs": {
+ "properties": {
+ "datasources": {
+ "type": "keyword"
+ },
+ "description": {
+ "type": "text"
+ },
+ "id": {
+ "type": "keyword"
+ },
+ "is_default": {
+ "type": "boolean"
+ },
+ "name": {
+ "type": "text"
+ },
+ "namespace": {
+ "type": "keyword"
+ },
+ "revision": {
+ "type": "integer"
+ },
+ "status": {
+ "type": "keyword"
+ },
+ "updated_by": {
+ "type": "keyword"
+ },
+ "updated_on": {
+ "type": "keyword"
+ }
+ }
+ },
+ "agent_events": {
+ "properties": {
+ "action_id": {
+ "type": "keyword"
+ },
+ "agent_id": {
+ "type": "keyword"
+ },
+ "config_id": {
+ "type": "keyword"
+ },
+ "data": {
+ "type": "text"
+ },
+ "message": {
+ "type": "text"
+ },
+ "payload": {
+ "type": "text"
+ },
+ "stream_id": {
+ "type": "keyword"
+ },
+ "subtype": {
+ "type": "keyword"
+ },
+ "timestamp": {
+ "type": "date"
+ },
+ "type": {
+ "type": "keyword"
+ }
+ }
+ },
+ "agents": {
+ "properties": {
+ "access_api_key_id": {
+ "type": "keyword"
+ },
+ "actions": {
+ "properties": {
+ "created_at": {
+ "type": "date"
+ },
+ "data": {
+ "type": "text"
+ },
+ "id": {
+ "type": "keyword"
+ },
+ "sent_at": {
+ "type": "date"
+ },
+ "type": {
+ "type": "keyword"
+ }
+ },
+ "type": "nested"
+ },
+ "active": {
+ "type": "boolean"
+ },
+ "config_id": {
+ "type": "keyword"
+ },
+ "config_newest_revision": {
+ "type": "integer"
+ },
+ "config_revision": {
+ "type": "integer"
+ },
+ "current_error_events": {
+ "type": "text"
+ },
+ "default_api_key": {
+ "type": "keyword"
+ },
+ "enrolled_at": {
+ "type": "date"
+ },
+ "last_checkin": {
+ "type": "date"
+ },
+ "last_updated": {
+ "type": "date"
+ },
+ "local_metadata": {
+ "type": "text"
+ },
+ "shared_id": {
+ "type": "keyword"
+ },
+ "type": {
+ "type": "keyword"
+ },
+ "updated_at": {
+ "type": "date"
+ },
+ "user_provided_metadata": {
+ "type": "text"
+ },
+ "version": {
+ "type": "keyword"
+ }
+ }
+ },
+ "alert": {
+ "properties": {
+ "actions": {
+ "properties": {
+ "actionRef": {
+ "type": "keyword"
+ },
+ "actionTypeId": {
+ "type": "keyword"
+ },
+ "group": {
+ "type": "keyword"
+ },
+ "params": {
+ "enabled": false,
+ "type": "object"
+ }
+ },
+ "type": "nested"
+ },
+ "alertTypeId": {
+ "type": "keyword"
+ },
+ "apiKey": {
+ "type": "binary"
+ },
+ "apiKeyOwner": {
+ "type": "keyword"
+ },
+ "consumer": {
+ "type": "keyword"
+ },
+ "createdAt": {
+ "type": "date"
+ },
+ "createdBy": {
+ "type": "keyword"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "muteAll": {
+ "type": "boolean"
+ },
+ "mutedInstanceIds": {
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "keyword": {
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "params": {
+ "enabled": false,
+ "type": "object"
+ },
+ "schedule": {
+ "properties": {
+ "interval": {
+ "type": "keyword"
+ }
+ }
+ },
+ "scheduledTaskId": {
+ "type": "keyword"
+ },
+ "tags": {
+ "type": "keyword"
+ },
+ "throttle": {
+ "type": "keyword"
+ },
+ "updatedBy": {
+ "type": "keyword"
+ }
+ }
+ },
+ "apm-indices": {
+ "properties": {
+ "apm_oss": {
+ "properties": {
+ "errorIndices": {
+ "type": "keyword"
+ },
+ "metricsIndices": {
+ "type": "keyword"
+ },
+ "onboardingIndices": {
+ "type": "keyword"
+ },
+ "sourcemapIndices": {
+ "type": "keyword"
+ },
+ "spanIndices": {
+ "type": "keyword"
+ },
+ "transactionIndices": {
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "apm-telemetry": {
+ "properties": {
+ "agents": {
+ "properties": {
+ "dotnet": {
+ "properties": {
+ "agent": {
+ "properties": {
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "service": {
+ "properties": {
+ "framework": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "language": {
+ "properties": {
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "runtime": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "go": {
+ "properties": {
+ "agent": {
+ "properties": {
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "service": {
+ "properties": {
+ "framework": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "language": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "runtime": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "java": {
+ "properties": {
+ "agent": {
+ "properties": {
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "service": {
+ "properties": {
+ "framework": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "language": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "runtime": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "js-base": {
+ "properties": {
+ "agent": {
+ "properties": {
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "service": {
+ "properties": {
+ "framework": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "language": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "runtime": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "nodejs": {
+ "properties": {
+ "agent": {
+ "properties": {
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "service": {
+ "properties": {
+ "framework": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "language": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "runtime": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "python": {
+ "properties": {
+ "agent": {
+ "properties": {
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "service": {
+ "properties": {
+ "framework": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "language": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "runtime": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "ruby": {
+ "properties": {
+ "agent": {
+ "properties": {
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "service": {
+ "properties": {
+ "framework": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "language": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "runtime": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "rum-js": {
+ "properties": {
+ "agent": {
+ "properties": {
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "service": {
+ "properties": {
+ "framework": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "language": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ },
+ "runtime": {
+ "properties": {
+ "composite": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 256,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "cardinality": {
+ "properties": {
+ "transaction": {
+ "properties": {
+ "name": {
+ "properties": {
+ "all_agents": {
+ "properties": {
+ "1d": {
+ "type": "long"
+ }
+ }
+ },
+ "rum": {
+ "properties": {
+ "1d": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "user_agent": {
+ "properties": {
+ "original": {
+ "properties": {
+ "all_agents": {
+ "properties": {
+ "1d": {
+ "type": "long"
+ }
+ }
+ },
+ "rum": {
+ "properties": {
+ "1d": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "counts": {
+ "properties": {
+ "agent_configuration": {
+ "properties": {
+ "all": {
+ "type": "long"
+ }
+ }
+ },
+ "error": {
+ "properties": {
+ "1d": {
+ "type": "long"
+ },
+ "all": {
+ "type": "long"
+ }
+ }
+ },
+ "max_error_groups_per_service": {
+ "properties": {
+ "1d": {
+ "type": "long"
+ }
+ }
+ },
+ "max_transaction_groups_per_service": {
+ "properties": {
+ "1d": {
+ "type": "long"
+ }
+ }
+ },
+ "metric": {
+ "properties": {
+ "1d": {
+ "type": "long"
+ },
+ "all": {
+ "type": "long"
+ }
+ }
+ },
+ "onboarding": {
+ "properties": {
+ "1d": {
+ "type": "long"
+ },
+ "all": {
+ "type": "long"
+ }
+ }
+ },
+ "services": {
+ "properties": {
+ "1d": {
+ "type": "long"
+ }
+ }
+ },
+ "sourcemap": {
+ "properties": {
+ "1d": {
+ "type": "long"
+ },
+ "all": {
+ "type": "long"
+ }
+ }
+ },
+ "span": {
+ "properties": {
+ "1d": {
+ "type": "long"
+ },
+ "all": {
+ "type": "long"
+ }
+ }
+ },
+ "traces": {
+ "properties": {
+ "1d": {
+ "type": "long"
+ }
+ }
+ },
+ "transaction": {
+ "properties": {
+ "1d": {
+ "type": "long"
+ },
+ "all": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "has_any_services": {
+ "type": "boolean"
+ },
+ "indices": {
+ "properties": {
+ "all": {
+ "properties": {
+ "total": {
+ "properties": {
+ "docs": {
+ "properties": {
+ "count": {
+ "type": "long"
+ }
+ }
+ },
+ "store": {
+ "properties": {
+ "size_in_bytes": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "shards": {
+ "properties": {
+ "total": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "integrations": {
+ "properties": {
+ "ml": {
+ "properties": {
+ "all_jobs_count": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "retainment": {
+ "properties": {
+ "error": {
+ "properties": {
+ "ms": {
+ "type": "long"
+ }
+ }
+ },
+ "metric": {
+ "properties": {
+ "ms": {
+ "type": "long"
+ }
+ }
+ },
+ "onboarding": {
+ "properties": {
+ "ms": {
+ "type": "long"
+ }
+ }
+ },
+ "span": {
+ "properties": {
+ "ms": {
+ "type": "long"
+ }
+ }
+ },
+ "transaction": {
+ "properties": {
+ "ms": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "services_per_agent": {
+ "properties": {
+ "dotnet": {
+ "null_value": 0,
+ "type": "long"
+ },
+ "go": {
+ "null_value": 0,
+ "type": "long"
+ },
+ "java": {
+ "null_value": 0,
+ "type": "long"
+ },
+ "js-base": {
+ "null_value": 0,
+ "type": "long"
+ },
+ "nodejs": {
+ "null_value": 0,
+ "type": "long"
+ },
+ "python": {
+ "null_value": 0,
+ "type": "long"
+ },
+ "ruby": {
+ "null_value": 0,
+ "type": "long"
+ },
+ "rum-js": {
+ "null_value": 0,
+ "type": "long"
+ }
+ }
+ },
+ "tasks": {
+ "properties": {
+ "agent_configuration": {
+ "properties": {
+ "took": {
+ "properties": {
+ "ms": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "agents": {
+ "properties": {
+ "took": {
+ "properties": {
+ "ms": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "cardinality": {
+ "properties": {
+ "took": {
+ "properties": {
+ "ms": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "groupings": {
+ "properties": {
+ "took": {
+ "properties": {
+ "ms": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "indices_stats": {
+ "properties": {
+ "took": {
+ "properties": {
+ "ms": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "integrations": {
+ "properties": {
+ "took": {
+ "properties": {
+ "ms": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "processor_events": {
+ "properties": {
+ "took": {
+ "properties": {
+ "ms": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "services": {
+ "properties": {
+ "took": {
+ "properties": {
+ "ms": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "versions": {
+ "properties": {
+ "took": {
+ "properties": {
+ "ms": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "version": {
+ "properties": {
+ "apm_server": {
+ "properties": {
+ "major": {
+ "type": "long"
+ },
+ "minor": {
+ "type": "long"
+ },
+ "patch": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "application_usage_totals": {
+ "properties": {
+ "appId": {
+ "type": "keyword"
+ },
+ "minutesOnScreen": {
+ "type": "float"
+ },
+ "numberOfClicks": {
+ "type": "long"
+ }
+ }
+ },
+ "application_usage_transactional": {
+ "properties": {
+ "appId": {
+ "type": "keyword"
+ },
+ "minutesOnScreen": {
+ "type": "float"
+ },
+ "numberOfClicks": {
+ "type": "long"
+ },
+ "timestamp": {
+ "type": "date"
+ }
+ }
+ },
+ "canvas-element": {
+ "dynamic": "false",
+ "properties": {
+ "@created": {
+ "type": "date"
+ },
+ "@timestamp": {
+ "type": "date"
+ },
+ "content": {
+ "type": "text"
+ },
+ "help": {
+ "type": "text"
+ },
+ "image": {
+ "type": "text"
+ },
+ "name": {
+ "fields": {
+ "keyword": {
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ }
+ }
+ },
+ "canvas-workpad": {
+ "dynamic": "false",
+ "properties": {
+ "@created": {
+ "type": "date"
+ },
+ "@timestamp": {
+ "type": "date"
+ },
+ "name": {
+ "fields": {
+ "keyword": {
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ }
+ }
+ },
+ "cases": {
+ "properties": {
+ "closed_at": {
+ "type": "date"
+ },
+ "closed_by": {
+ "properties": {
+ "email": {
+ "type": "keyword"
+ },
+ "full_name": {
+ "type": "keyword"
+ },
+ "username": {
+ "type": "keyword"
+ }
+ }
+ },
+ "created_at": {
+ "type": "date"
+ },
+ "created_by": {
+ "properties": {
+ "email": {
+ "type": "keyword"
+ },
+ "full_name": {
+ "type": "keyword"
+ },
+ "username": {
+ "type": "keyword"
+ }
+ }
+ },
+ "description": {
+ "type": "text"
+ },
+ "external_service": {
+ "properties": {
+ "connector_id": {
+ "type": "keyword"
+ },
+ "connector_name": {
+ "type": "keyword"
+ },
+ "external_id": {
+ "type": "keyword"
+ },
+ "external_title": {
+ "type": "text"
+ },
+ "external_url": {
+ "type": "text"
+ },
+ "pushed_at": {
+ "type": "date"
+ },
+ "pushed_by": {
+ "properties": {
+ "email": {
+ "type": "keyword"
+ },
+ "full_name": {
+ "type": "keyword"
+ },
+ "username": {
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "status": {
+ "type": "keyword"
+ },
+ "tags": {
+ "type": "keyword"
+ },
+ "title": {
+ "type": "keyword"
+ },
+ "updated_at": {
+ "type": "date"
+ },
+ "updated_by": {
+ "properties": {
+ "email": {
+ "type": "keyword"
+ },
+ "full_name": {
+ "type": "keyword"
+ },
+ "username": {
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "cases-comments": {
+ "properties": {
+ "comment": {
+ "type": "text"
+ },
+ "created_at": {
+ "type": "date"
+ },
+ "created_by": {
+ "properties": {
+ "email": {
+ "type": "keyword"
+ },
+ "full_name": {
+ "type": "keyword"
+ },
+ "username": {
+ "type": "keyword"
+ }
+ }
+ },
+ "pushed_at": {
+ "type": "date"
+ },
+ "pushed_by": {
+ "properties": {
+ "email": {
+ "type": "keyword"
+ },
+ "full_name": {
+ "type": "keyword"
+ },
+ "username": {
+ "type": "keyword"
+ }
+ }
+ },
+ "updated_at": {
+ "type": "date"
+ },
+ "updated_by": {
+ "properties": {
+ "email": {
+ "type": "keyword"
+ },
+ "full_name": {
+ "type": "keyword"
+ },
+ "username": {
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "cases-configure": {
+ "properties": {
+ "closure_type": {
+ "type": "keyword"
+ },
+ "connector_id": {
+ "type": "keyword"
+ },
+ "connector_name": {
+ "type": "keyword"
+ },
+ "created_at": {
+ "type": "date"
+ },
+ "created_by": {
+ "properties": {
+ "email": {
+ "type": "keyword"
+ },
+ "full_name": {
+ "type": "keyword"
+ },
+ "username": {
+ "type": "keyword"
+ }
+ }
+ },
+ "updated_at": {
+ "type": "date"
+ },
+ "updated_by": {
+ "properties": {
+ "email": {
+ "type": "keyword"
+ },
+ "full_name": {
+ "type": "keyword"
+ },
+ "username": {
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "cases-user-actions": {
+ "properties": {
+ "action": {
+ "type": "keyword"
+ },
+ "action_at": {
+ "type": "date"
+ },
+ "action_by": {
+ "properties": {
+ "email": {
+ "type": "keyword"
+ },
+ "full_name": {
+ "type": "keyword"
+ },
+ "username": {
+ "type": "keyword"
+ }
+ }
+ },
+ "action_field": {
+ "type": "keyword"
+ },
+ "new_value": {
+ "type": "text"
+ },
+ "old_value": {
+ "type": "text"
+ }
+ }
+ },
+ "config": {
+ "dynamic": "true",
+ "properties": {
+ "buildNum": {
+ "type": "keyword"
+ },
+ "dateFormat:tz": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "defaultIndex": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ }
+ }
+ },
+ "dashboard": {
+ "properties": {
+ "description": {
+ "type": "text"
+ },
+ "hits": {
+ "type": "integer"
+ },
+ "kibanaSavedObjectMeta": {
+ "properties": {
+ "searchSourceJSON": {
+ "type": "text"
+ }
+ }
+ },
+ "optionsJSON": {
+ "type": "text"
+ },
+ "panelsJSON": {
+ "type": "text"
+ },
+ "refreshInterval": {
+ "properties": {
+ "display": {
+ "type": "keyword"
+ },
+ "pause": {
+ "type": "boolean"
+ },
+ "section": {
+ "type": "integer"
+ },
+ "value": {
+ "type": "integer"
+ }
+ }
+ },
+ "timeFrom": {
+ "type": "keyword"
+ },
+ "timeRestore": {
+ "type": "boolean"
+ },
+ "timeTo": {
+ "type": "keyword"
+ },
+ "title": {
+ "type": "text"
+ },
+ "version": {
+ "type": "integer"
+ }
+ }
+ },
+ "datasources": {
+ "properties": {
+ "config_id": {
+ "type": "keyword"
+ },
+ "description": {
+ "type": "text"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "inputs": {
+ "properties": {
+ "config": {
+ "type": "flattened"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "processors": {
+ "type": "keyword"
+ },
+ "streams": {
+ "properties": {
+ "config": {
+ "type": "flattened"
+ },
+ "dataset": {
+ "type": "keyword"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "id": {
+ "type": "keyword"
+ },
+ "processors": {
+ "type": "keyword"
+ }
+ },
+ "type": "nested"
+ },
+ "type": {
+ "type": "keyword"
+ }
+ },
+ "type": "nested"
+ },
+ "name": {
+ "type": "keyword"
+ },
+ "namespace": {
+ "type": "keyword"
+ },
+ "output_id": {
+ "type": "keyword"
+ },
+ "package": {
+ "properties": {
+ "name": {
+ "type": "keyword"
+ },
+ "title": {
+ "type": "keyword"
+ },
+ "version": {
+ "type": "keyword"
+ }
+ }
+ },
+ "revision": {
+ "type": "integer"
+ }
+ }
+ },
+ "enrollment_api_keys": {
+ "properties": {
+ "active": {
+ "type": "boolean"
+ },
+ "api_key": {
+ "type": "binary"
+ },
+ "api_key_id": {
+ "type": "keyword"
+ },
+ "config_id": {
+ "type": "keyword"
+ },
+ "created_at": {
+ "type": "date"
+ },
+ "expire_at": {
+ "type": "date"
+ },
+ "name": {
+ "type": "keyword"
+ },
+ "type": {
+ "type": "keyword"
+ },
+ "updated_at": {
+ "type": "date"
+ }
+ }
+ },
+ "epm-package": {
+ "properties": {
+ "installed": {
+ "properties": {
+ "id": {
+ "type": "keyword"
+ },
+ "type": {
+ "type": "keyword"
+ }
+ },
+ "type": "nested"
+ },
+ "name": {
+ "type": "keyword"
+ },
+ "version": {
+ "type": "keyword"
+ }
+ }
+ },
+ "file-upload-telemetry": {
+ "properties": {
+ "filesUploadedTotalCount": {
+ "type": "long"
+ }
+ }
+ },
+ "graph-workspace": {
+ "properties": {
+ "description": {
+ "type": "text"
+ },
+ "kibanaSavedObjectMeta": {
+ "properties": {
+ "searchSourceJSON": {
+ "type": "text"
+ }
+ }
+ },
+ "numLinks": {
+ "type": "integer"
+ },
+ "numVertices": {
+ "type": "integer"
+ },
+ "title": {
+ "type": "text"
+ },
+ "version": {
+ "type": "integer"
+ },
+ "wsState": {
+ "type": "text"
+ }
+ }
+ },
+ "index-pattern": {
+ "properties": {
+ "fieldFormatMap": {
+ "type": "text"
+ },
+ "fields": {
+ "type": "text"
+ },
+ "intervalName": {
+ "type": "keyword"
+ },
+ "notExpandable": {
+ "type": "boolean"
+ },
+ "sourceFilters": {
+ "type": "text"
+ },
+ "timeFieldName": {
+ "type": "keyword"
+ },
+ "title": {
+ "type": "text"
+ },
+ "type": {
+ "type": "keyword"
+ },
+ "typeMeta": {
+ "type": "keyword"
+ }
+ }
+ },
+ "infrastructure-ui-source": {
+ "properties": {
+ "description": {
+ "type": "text"
+ },
+ "fields": {
+ "properties": {
+ "container": {
+ "type": "keyword"
+ },
+ "host": {
+ "type": "keyword"
+ },
+ "pod": {
+ "type": "keyword"
+ },
+ "tiebreaker": {
+ "type": "keyword"
+ },
+ "timestamp": {
+ "type": "keyword"
+ }
+ }
+ },
+ "logAlias": {
+ "type": "keyword"
+ },
+ "logColumns": {
+ "properties": {
+ "fieldColumn": {
+ "properties": {
+ "field": {
+ "type": "keyword"
+ },
+ "id": {
+ "type": "keyword"
+ }
+ }
+ },
+ "messageColumn": {
+ "properties": {
+ "id": {
+ "type": "keyword"
+ }
+ }
+ },
+ "timestampColumn": {
+ "properties": {
+ "id": {
+ "type": "keyword"
+ }
+ }
+ }
+ },
+ "type": "nested"
+ },
+ "metricAlias": {
+ "type": "keyword"
+ },
+ "name": {
+ "type": "text"
+ }
+ }
+ },
+ "inventory-view": {
+ "properties": {
+ "autoBounds": {
+ "type": "boolean"
+ },
+ "autoReload": {
+ "type": "boolean"
+ },
+ "boundsOverride": {
+ "properties": {
+ "max": {
+ "type": "integer"
+ },
+ "min": {
+ "type": "integer"
+ }
+ }
+ },
+ "customMetrics": {
+ "properties": {
+ "aggregation": {
+ "type": "keyword"
+ },
+ "field": {
+ "type": "keyword"
+ },
+ "id": {
+ "type": "keyword"
+ },
+ "label": {
+ "type": "keyword"
+ },
+ "type": {
+ "type": "keyword"
+ }
+ },
+ "type": "nested"
+ },
+ "customOptions": {
+ "properties": {
+ "field": {
+ "type": "keyword"
+ },
+ "text": {
+ "type": "keyword"
+ }
+ },
+ "type": "nested"
+ },
+ "filterQuery": {
+ "properties": {
+ "expression": {
+ "type": "keyword"
+ },
+ "kind": {
+ "type": "keyword"
+ }
+ }
+ },
+ "groupBy": {
+ "properties": {
+ "field": {
+ "type": "keyword"
+ },
+ "label": {
+ "type": "keyword"
+ }
+ },
+ "type": "nested"
+ },
+ "metric": {
+ "properties": {
+ "aggregation": {
+ "type": "keyword"
+ },
+ "field": {
+ "type": "keyword"
+ },
+ "id": {
+ "type": "keyword"
+ },
+ "label": {
+ "type": "keyword"
+ },
+ "type": {
+ "type": "keyword"
+ }
+ }
+ },
+ "name": {
+ "type": "keyword"
+ },
+ "nodeType": {
+ "type": "keyword"
+ },
+ "time": {
+ "type": "integer"
+ },
+ "view": {
+ "type": "keyword"
+ }
+ }
+ },
+ "kql-telemetry": {
+ "properties": {
+ "optInCount": {
+ "type": "long"
+ },
+ "optOutCount": {
+ "type": "long"
+ }
+ }
+ },
+ "lens": {
+ "properties": {
+ "expression": {
+ "index": false,
+ "type": "keyword"
+ },
+ "state": {
+ "type": "flattened"
+ },
+ "title": {
+ "type": "text"
+ },
+ "visualizationType": {
+ "type": "keyword"
+ }
+ }
+ },
+ "lens-ui-telemetry": {
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "date": {
+ "type": "date"
+ },
+ "name": {
+ "type": "keyword"
+ },
+ "type": {
+ "type": "keyword"
+ }
+ }
+ },
+ "map": {
+ "properties": {
+ "bounds": {
+ "type": "geo_shape"
+ },
+ "description": {
+ "type": "text"
+ },
+ "layerListJSON": {
+ "type": "text"
+ },
+ "mapStateJSON": {
+ "type": "text"
+ },
+ "title": {
+ "type": "text"
+ },
+ "uiStateJSON": {
+ "type": "text"
+ },
+ "version": {
+ "type": "integer"
+ }
+ }
+ },
+ "maps-telemetry": {
+ "properties": {
+ "attributesPerMap": {
+ "properties": {
+ "dataSourcesCount": {
+ "properties": {
+ "avg": {
+ "type": "long"
+ },
+ "max": {
+ "type": "long"
+ },
+ "min": {
+ "type": "long"
+ }
+ }
+ },
+ "emsVectorLayersCount": {
+ "dynamic": "true",
+ "type": "object"
+ },
+ "layerTypesCount": {
+ "dynamic": "true",
+ "type": "object"
+ },
+ "layersCount": {
+ "properties": {
+ "avg": {
+ "type": "long"
+ },
+ "max": {
+ "type": "long"
+ },
+ "min": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "indexPatternsWithGeoFieldCount": {
+ "type": "long"
+ },
+ "mapsTotalCount": {
+ "type": "long"
+ },
+ "settings": {
+ "properties": {
+ "showMapVisualizationTypes": {
+ "type": "boolean"
+ }
+ }
+ },
+ "timeCaptured": {
+ "type": "date"
+ }
+ }
+ },
+ "metrics-explorer-view": {
+ "properties": {
+ "chartOptions": {
+ "properties": {
+ "stack": {
+ "type": "boolean"
+ },
+ "type": {
+ "type": "keyword"
+ },
+ "yAxisMode": {
+ "type": "keyword"
+ }
+ }
+ },
+ "currentTimerange": {
+ "properties": {
+ "from": {
+ "type": "keyword"
+ },
+ "interval": {
+ "type": "keyword"
+ },
+ "to": {
+ "type": "keyword"
+ }
+ }
+ },
+ "name": {
+ "type": "keyword"
+ },
+ "options": {
+ "properties": {
+ "aggregation": {
+ "type": "keyword"
+ },
+ "filterQuery": {
+ "type": "keyword"
+ },
+ "groupBy": {
+ "type": "keyword"
+ },
+ "limit": {
+ "type": "integer"
+ },
+ "metrics": {
+ "properties": {
+ "aggregation": {
+ "type": "keyword"
+ },
+ "color": {
+ "type": "keyword"
+ },
+ "field": {
+ "type": "keyword"
+ },
+ "label": {
+ "type": "keyword"
+ }
+ },
+ "type": "nested"
+ }
+ }
+ }
+ }
+ },
+ "migrationVersion": {
+ "dynamic": "true",
+ "properties": {
+ "canvas-workpad": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "dashboard": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "graph-workspace": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "index-pattern": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "map": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "space": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "visualization": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ }
+ }
+ },
+ "ml-telemetry": {
+ "properties": {
+ "file_data_visualizer": {
+ "properties": {
+ "index_creation_count": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "namespace": {
+ "type": "keyword"
+ },
+ "outputs": {
+ "properties": {
+ "api_key": {
+ "type": "keyword"
+ },
+ "ca_sha256": {
+ "type": "keyword"
+ },
+ "config": {
+ "type": "flattened"
+ },
+ "fleet_enroll_password": {
+ "type": "binary"
+ },
+ "fleet_enroll_username": {
+ "type": "binary"
+ },
+ "hosts": {
+ "type": "keyword"
+ },
+ "is_default": {
+ "type": "boolean"
+ },
+ "name": {
+ "type": "keyword"
+ },
+ "type": {
+ "type": "keyword"
+ }
+ }
+ },
+ "query": {
+ "properties": {
+ "description": {
+ "type": "text"
+ },
+ "filters": {
+ "enabled": false,
+ "type": "object"
+ },
+ "query": {
+ "properties": {
+ "language": {
+ "type": "keyword"
+ },
+ "query": {
+ "index": false,
+ "type": "keyword"
+ }
+ }
+ },
+ "timefilter": {
+ "enabled": false,
+ "type": "object"
+ },
+ "title": {
+ "type": "text"
+ }
+ }
+ },
+ "references": {
+ "properties": {
+ "id": {
+ "type": "keyword"
+ },
+ "name": {
+ "type": "keyword"
+ },
+ "type": {
+ "type": "keyword"
+ }
+ },
+ "type": "nested"
+ },
+ "sample-data-telemetry": {
+ "properties": {
+ "installCount": {
+ "type": "long"
+ },
+ "unInstallCount": {
+ "type": "long"
+ }
+ }
+ },
+ "search": {
+ "properties": {
+ "columns": {
+ "type": "keyword"
+ },
+ "description": {
+ "type": "text"
+ },
+ "hits": {
+ "type": "integer"
+ },
+ "kibanaSavedObjectMeta": {
+ "properties": {
+ "searchSourceJSON": {
+ "type": "text"
+ }
+ }
+ },
+ "sort": {
+ "type": "keyword"
+ },
+ "title": {
+ "type": "text"
+ },
+ "version": {
+ "type": "integer"
+ }
+ }
+ },
+ "server": {
+ "properties": {
+ "uuid": {
+ "type": "keyword"
+ }
+ }
+ },
+ "siem-detection-engine-rule-status": {
+ "properties": {
+ "alertId": {
+ "type": "keyword"
+ },
+ "bulkCreateTimeDurations": {
+ "type": "float"
+ },
+ "gap": {
+ "type": "text"
+ },
+ "lastFailureAt": {
+ "type": "date"
+ },
+ "lastFailureMessage": {
+ "type": "text"
+ },
+ "lastLookBackDate": {
+ "type": "date"
+ },
+ "lastSuccessAt": {
+ "type": "date"
+ },
+ "lastSuccessMessage": {
+ "type": "text"
+ },
+ "searchAfterTimeDurations": {
+ "type": "float"
+ },
+ "status": {
+ "type": "keyword"
+ },
+ "statusDate": {
+ "type": "date"
+ }
+ }
+ },
+ "siem-ui-timeline": {
+ "properties": {
+ "columns": {
+ "properties": {
+ "aggregatable": {
+ "type": "boolean"
+ },
+ "category": {
+ "type": "keyword"
+ },
+ "columnHeaderType": {
+ "type": "keyword"
+ },
+ "description": {
+ "type": "text"
+ },
+ "example": {
+ "type": "text"
+ },
+ "id": {
+ "type": "keyword"
+ },
+ "indexes": {
+ "type": "keyword"
+ },
+ "name": {
+ "type": "text"
+ },
+ "placeholder": {
+ "type": "text"
+ },
+ "searchable": {
+ "type": "boolean"
+ },
+ "type": {
+ "type": "keyword"
+ }
+ }
+ },
+ "created": {
+ "type": "date"
+ },
+ "createdBy": {
+ "type": "text"
+ },
+ "dataProviders": {
+ "properties": {
+ "and": {
+ "properties": {
+ "enabled": {
+ "type": "boolean"
+ },
+ "excluded": {
+ "type": "boolean"
+ },
+ "id": {
+ "type": "keyword"
+ },
+ "kqlQuery": {
+ "type": "text"
+ },
+ "name": {
+ "type": "text"
+ },
+ "queryMatch": {
+ "properties": {
+ "displayField": {
+ "type": "text"
+ },
+ "displayValue": {
+ "type": "text"
+ },
+ "field": {
+ "type": "text"
+ },
+ "operator": {
+ "type": "text"
+ },
+ "value": {
+ "type": "text"
+ }
+ }
+ }
+ }
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "excluded": {
+ "type": "boolean"
+ },
+ "id": {
+ "type": "keyword"
+ },
+ "kqlQuery": {
+ "type": "text"
+ },
+ "name": {
+ "type": "text"
+ },
+ "queryMatch": {
+ "properties": {
+ "displayField": {
+ "type": "text"
+ },
+ "displayValue": {
+ "type": "text"
+ },
+ "field": {
+ "type": "text"
+ },
+ "operator": {
+ "type": "text"
+ },
+ "value": {
+ "type": "text"
+ }
+ }
+ }
+ }
+ },
+ "dateRange": {
+ "properties": {
+ "end": {
+ "type": "date"
+ },
+ "start": {
+ "type": "date"
+ }
+ }
+ },
+ "description": {
+ "type": "text"
+ },
+ "eventType": {
+ "type": "keyword"
+ },
+ "favorite": {
+ "properties": {
+ "favoriteDate": {
+ "type": "date"
+ },
+ "fullName": {
+ "type": "text"
+ },
+ "keySearch": {
+ "type": "text"
+ },
+ "userName": {
+ "type": "text"
+ }
+ }
+ },
+ "filters": {
+ "properties": {
+ "exists": {
+ "type": "text"
+ },
+ "match_all": {
+ "type": "text"
+ },
+ "meta": {
+ "properties": {
+ "alias": {
+ "type": "text"
+ },
+ "controlledBy": {
+ "type": "text"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "field": {
+ "type": "text"
+ },
+ "formattedValue": {
+ "type": "text"
+ },
+ "index": {
+ "type": "keyword"
+ },
+ "key": {
+ "type": "keyword"
+ },
+ "negate": {
+ "type": "boolean"
+ },
+ "params": {
+ "type": "text"
+ },
+ "type": {
+ "type": "keyword"
+ },
+ "value": {
+ "type": "text"
+ }
+ }
+ },
+ "missing": {
+ "type": "text"
+ },
+ "query": {
+ "type": "text"
+ },
+ "range": {
+ "type": "text"
+ },
+ "script": {
+ "type": "text"
+ }
+ }
+ },
+ "kqlMode": {
+ "type": "keyword"
+ },
+ "kqlQuery": {
+ "properties": {
+ "filterQuery": {
+ "properties": {
+ "kuery": {
+ "properties": {
+ "expression": {
+ "type": "text"
+ },
+ "kind": {
+ "type": "keyword"
+ }
+ }
+ },
+ "serializedQuery": {
+ "type": "text"
+ }
+ }
+ }
+ }
+ },
+ "savedQueryId": {
+ "type": "keyword"
+ },
+ "sort": {
+ "properties": {
+ "columnId": {
+ "type": "keyword"
+ },
+ "sortDirection": {
+ "type": "keyword"
+ }
+ }
+ },
+ "title": {
+ "type": "text"
+ },
+ "updated": {
+ "type": "date"
+ },
+ "updatedBy": {
+ "type": "text"
+ }
+ }
+ },
+ "siem-ui-timeline-note": {
+ "properties": {
+ "created": {
+ "type": "date"
+ },
+ "createdBy": {
+ "type": "text"
+ },
+ "eventId": {
+ "type": "keyword"
+ },
+ "note": {
+ "type": "text"
+ },
+ "timelineId": {
+ "type": "keyword"
+ },
+ "updated": {
+ "type": "date"
+ },
+ "updatedBy": {
+ "type": "text"
+ }
+ }
+ },
+ "siem-ui-timeline-pinned-event": {
+ "properties": {
+ "created": {
+ "type": "date"
+ },
+ "createdBy": {
+ "type": "text"
+ },
+ "eventId": {
+ "type": "keyword"
+ },
+ "timelineId": {
+ "type": "keyword"
+ },
+ "updated": {
+ "type": "date"
+ },
+ "updatedBy": {
+ "type": "text"
+ }
+ }
+ },
+ "space": {
+ "properties": {
+ "_reserved": {
+ "type": "boolean"
+ },
+ "color": {
+ "type": "keyword"
+ },
+ "description": {
+ "type": "text"
+ },
+ "disabledFeatures": {
+ "type": "keyword"
+ },
+ "imageUrl": {
+ "index": false,
+ "type": "text"
+ },
+ "initials": {
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 2048,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ }
+ }
+ },
+ "telemetry": {
+ "properties": {
+ "allowChangingOptInStatus": {
+ "type": "boolean"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "lastReported": {
+ "type": "date"
+ },
+ "lastVersionChecked": {
+ "type": "keyword"
+ },
+ "reportFailureCount": {
+ "type": "integer"
+ },
+ "reportFailureVersion": {
+ "type": "keyword"
+ },
+ "sendUsageFrom": {
+ "type": "keyword"
+ },
+ "userHasSeenNotice": {
+ "type": "boolean"
+ }
+ }
+ },
+ "timelion-sheet": {
+ "properties": {
+ "description": {
+ "type": "text"
+ },
+ "hits": {
+ "type": "integer"
+ },
+ "kibanaSavedObjectMeta": {
+ "properties": {
+ "searchSourceJSON": {
+ "type": "text"
+ }
+ }
+ },
+ "timelion_chart_height": {
+ "type": "integer"
+ },
+ "timelion_columns": {
+ "type": "integer"
+ },
+ "timelion_interval": {
+ "type": "keyword"
+ },
+ "timelion_other_interval": {
+ "type": "keyword"
+ },
+ "timelion_rows": {
+ "type": "integer"
+ },
+ "timelion_sheet": {
+ "type": "text"
+ },
+ "title": {
+ "type": "text"
+ },
+ "version": {
+ "type": "integer"
+ }
+ }
+ },
+ "tsvb-validation-telemetry": {
+ "properties": {
+ "failedRequests": {
+ "type": "long"
+ }
+ }
+ },
+ "type": {
+ "type": "keyword"
+ },
+ "ui-metric": {
+ "properties": {
+ "count": {
+ "type": "integer"
+ }
+ }
+ },
+ "updated_at": {
+ "type": "date"
+ },
+ "upgrade-assistant-reindex-operation": {
+ "dynamic": "true",
+ "properties": {
+ "indexName": {
+ "type": "keyword"
+ },
+ "status": {
+ "type": "integer"
+ }
+ }
+ },
+ "upgrade-assistant-telemetry": {
+ "properties": {
+ "features": {
+ "properties": {
+ "deprecation_logging": {
+ "properties": {
+ "enabled": {
+ "null_value": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "ui_open": {
+ "properties": {
+ "cluster": {
+ "null_value": 0,
+ "type": "long"
+ },
+ "indices": {
+ "null_value": 0,
+ "type": "long"
+ },
+ "overview": {
+ "null_value": 0,
+ "type": "long"
+ }
+ }
+ },
+ "ui_reindex": {
+ "properties": {
+ "close": {
+ "null_value": 0,
+ "type": "long"
+ },
+ "open": {
+ "null_value": 0,
+ "type": "long"
+ },
+ "start": {
+ "null_value": 0,
+ "type": "long"
+ },
+ "stop": {
+ "null_value": 0,
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "uptime-dynamic-settings": {
+ "properties": {
+ "heartbeatIndices": {
+ "type": "keyword"
+ }
+ }
+ },
+ "url": {
+ "properties": {
+ "accessCount": {
+ "type": "long"
+ },
+ "accessDate": {
+ "type": "date"
+ },
+ "createDate": {
+ "type": "date"
+ },
+ "url": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 2048,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ }
+ }
+ },
+ "visualization": {
+ "properties": {
+ "description": {
+ "type": "text"
+ },
+ "kibanaSavedObjectMeta": {
+ "properties": {
+ "searchSourceJSON": {
+ "type": "text"
+ }
+ }
+ },
+ "savedSearchRefName": {
+ "type": "keyword"
+ },
+ "title": {
+ "type": "text"
+ },
+ "uiStateJSON": {
+ "type": "text"
+ },
+ "version": {
+ "type": "integer"
+ },
+ "visState": {
+ "type": "text"
+ }
+ }
+ }
+ }
+ },
+ "settings": {
+ "index": {
+ "auto_expand_replicas": "0-1",
+ "number_of_replicas": "0",
+ "number_of_shards": "1"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/x-pack/test/functional/services/machine_learning/api.ts b/x-pack/test/functional/services/machine_learning/api.ts
index 74dc5912df36..afc2567f3cce 100644
--- a/x-pack/test/functional/services/machine_learning/api.ts
+++ b/x-pack/test/functional/services/machine_learning/api.ts
@@ -277,6 +277,16 @@ export function MachineLearningAPIProvider({ getService }: FtrProviderContext) {
return await esSupertest.get(`/_ml/anomaly_detectors/${jobId}`).expect(200);
},
+ async waitForAnomalyDetectionJobToExist(jobId: string) {
+ await retry.waitForWithTimeout(`'${jobId}' to exist`, 5 * 1000, async () => {
+ if (await this.getAnomalyDetectionJob(jobId)) {
+ return true;
+ } else {
+ throw new Error(`expected anomaly detection job '${jobId}' to exist`);
+ }
+ });
+ },
+
async createAnomalyDetectionJob(jobConfig: Job) {
const jobId = jobConfig.job_id;
log.debug(`Creating anomaly detection job with id '${jobId}'...`);
@@ -285,19 +295,23 @@ export function MachineLearningAPIProvider({ getService }: FtrProviderContext) {
.send(jobConfig)
.expect(200);
- await retry.waitForWithTimeout(`'${jobId}' to be created`, 5 * 1000, async () => {
- if (await this.getAnomalyDetectionJob(jobId)) {
- return true;
- } else {
- throw new Error(`expected anomaly detection job '${jobId}' to be created`);
- }
- });
+ await this.waitForAnomalyDetectionJobToExist(jobId);
},
async getDatafeed(datafeedId: string) {
return await esSupertest.get(`/_ml/datafeeds/${datafeedId}`).expect(200);
},
+ async waitForDatafeedToExist(datafeedId: string) {
+ await retry.waitForWithTimeout(`'${datafeedId}' to exist`, 5 * 1000, async () => {
+ if (await this.getDatafeed(datafeedId)) {
+ return true;
+ } else {
+ throw new Error(`expected datafeed '${datafeedId}' to exist`);
+ }
+ });
+ },
+
async createDatafeed(datafeedConfig: Datafeed) {
const datafeedId = datafeedConfig.datafeed_id;
log.debug(`Creating datafeed with id '${datafeedId}'...`);
@@ -306,13 +320,7 @@ export function MachineLearningAPIProvider({ getService }: FtrProviderContext) {
.send(datafeedConfig)
.expect(200);
- await retry.waitForWithTimeout(`'${datafeedId}' to be created`, 5 * 1000, async () => {
- if (await this.getDatafeed(datafeedId)) {
- return true;
- } else {
- throw new Error(`expected datafeed '${datafeedId}' to be created`);
- }
- });
+ await this.waitForDatafeedToExist(datafeedId);
},
async openAnomalyDetectionJob(jobId: string) {
diff --git a/x-pack/test/functional/services/machine_learning/security_common.ts b/x-pack/test/functional/services/machine_learning/security_common.ts
index d59c1edcb00a..1145b6f93a4f 100644
--- a/x-pack/test/functional/services/machine_learning/security_common.ts
+++ b/x-pack/test/functional/services/machine_learning/security_common.ts
@@ -12,6 +12,7 @@ export type MlSecurityCommon = ProvidedType
{username} @@ -65,8 +70,8 @@ const renderUsers = ( data-test-subj="user-list-email-button" onClick={handleSendEmail.bind(null, email)} iconType="email" - aria-label="email" - isDisabled={email == null} + aria-label={i18n.SEND_EMAIL_ARIA(fullName ? fullName : username ?? '')} + isDisabled={isEmpty(email)} />