; getFilters: () => Promise<",
{
"pluginId": "@kbn/es-query",
"scope": "common",
@@ -6422,14 +6430,6 @@
"section": "def-common.Adapters",
"text": "Adapters"
},
- " | undefined; openInspector: () => ",
- {
- "pluginId": "@kbn/core-mount-utils-browser",
- "scope": "common",
- "docId": "kibKbnCoreMountUtilsBrowserPluginApi",
- "section": "def-common.OverlayRef",
- "text": "OverlayRef"
- },
" | undefined; transferCustomizationsToUiState: () => void; hasInspector: () => boolean; onContainerLoading: () => void; onContainerData: () => void; onContainerRender: () => void; onContainerError: (error: ",
{
"pluginId": "expressions",
diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx
index 85f08cb6f5b4a..72ddb254498f0 100644
--- a/api_docs/visualizations.mdx
+++ b/api_docs/visualizations.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations
title: "visualizations"
image: https://source.unsplash.com/400x175/?github
description: API docs for the visualizations plugin
-date: 2023-07-17
+date: 2023-07-18
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations']
---
import visualizationsObj from './visualizations.devdocs.json';
diff --git a/docs/api-generated/rules/rule-apis-passthru.asciidoc b/docs/api-generated/rules/rule-apis-passthru.asciidoc
index e1cf66a214f31..fdcc9bc78bfd5 100644
--- a/docs/api-generated/rules/rule-apis-passthru.asciidoc
+++ b/docs/api-generated/rules/rule-apis-passthru.asciidoc
@@ -53,7 +53,7 @@ Any modifications made to this file will be overwritten.
Up
post /s/{spaceId}/api/alerting/rule
Creates a rule with a randomly generated rule identifier. (createRule)
- You must have all
privileges for the appropriate Kibana features, depending on the consumer
and rule_type_id
of the rule you're creating. For example, you must have privileges for the Management > Stack rules feature, Analytics > Discover and Machine Learning features, Observability features, or Security features. If the rule has actions, you must also have read
privileges for the Management > Actions and Connectors feature. NOTE: This API supports only token-based authentication. When you create a rule, it identifies which roles you have at that point in time. Thereafter, when the rule performs queries, it uses those security privileges. If a user with different privileges updates the rule, its behavior might change.
+ To create a rule, you must have all
privileges for the appropriate Kibana features, depending on the consumer
and rule_type_id
of the rule you're creating. For example, you must have privileges for the Management > Stack rules feature, Analytics > Discover and Machine Learning features, Observability features, or Security features. If the rule has actions, you must also have read
privileges for the Management > Actions and Connectors feature. This API supports both key- and token-based authentication. To use key-based authentication, create an API key in Kibana and use it in the header of the API call. To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically. In both cases, the API key is subsequently used for authorization when the rule runs.
Path parameters
@@ -289,7 +289,7 @@ Any modifications made to this file will be overwritten.
Up
post /s/{spaceId}/api/alerting/rule/{ruleId}
Creates a rule with a specific rule identifier. (createRuleId)
- You must have all
privileges for the appropriate Kibana features, depending on the consumer
and rule_type_id
of the rule you're creating. For example, you must have privileges for the Management > Stack rules feature, Analytics > Discover and Machine Learning features, Observability features, or Security features. If the rule has actions, you must also have read
privileges for the Management > Actions and Connectors feature. NOTE: This API supports only token-based authentication. When you create a rule, it identifies which roles you have at that point in time. Thereafter, when the rule performs queries, it uses those security privileges. If a user with different privileges updates the rule, its behavior might change.
+ To create a rule, you must have all
privileges for the appropriate Kibana features, depending on the consumer
and rule_type_id
of the rule you're creating. For example, you must have privileges for the Management > Stack rules feature, Analytics > Discover and Machine Learning features, Observability features, or Security features. If the rule has actions, you must also have read
privileges for the Management > Actions and Connectors feature. This API supports both key- and token-based authentication. To use key-based authentication, create an API key in Kibana and use it in the header of the API call. To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically. In both cases, the API key is subsequently used for authorization when the rule runs.
Path parameters
@@ -527,7 +527,7 @@ Any modifications made to this file will be overwritten.
Up
delete /s/{spaceId}/api/alerting/rule/{ruleId}
Deletes a rule. (deleteRule)
- You must have all
privileges for the appropriate Kibana features, depending on the consumer
and rule_type_id
of the rule you're deleting. For example, the Management > Stack Rules feature, Analytics > Discover or Machine Learning features, Observability, or Security features. WARNING: After you delete a rule, you cannot recover it.
+ To delete a rule, you must have all
privileges for the appropriate Kibana features, depending on the consumer
and rule_type_id
of the rule you're deleting. For example, the Management > Stack Rules feature, Analytics > Discover or Machine Learning features, Observability, or Security features. WARNING: After you delete a rule, you cannot recover it. If the API key that is used by the rule was created automatically, it is deleted.
Path parameters
@@ -629,7 +629,7 @@ Any modifications made to this file will be overwritten.
Up
post /s/{spaceId}/api/alerting/rule/{ruleId}/_enable
Enables a rule. (enableRule)
- This API supports token-based authentication only. You must have all
privileges for the appropriate Kibana features, depending on the consumer
and rule_type_id
of the rule. For example, the Management > Stack Rules feature, Analytics > Discover and Machine Learning features, Observability, and Security features.
+ To enable a rule, you must have all
privileges for the appropriate Kibana features, depending on the consumer
and rule_type_id
of the rule. For example, the Management > Stack Rules feature, Analytics > Discover and Machine Learning features, Observability, and Security features. This API supports both key- and token-based authentication. To use key-based authentication, create an API key in Kibana and use it in the header of the API call. To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically. In both cases, the API key is subsequently used for authorization when the rule runs.
Path parameters
@@ -2594,7 +2594,7 @@ Any modifications made to this file will be overwritten.
Up
put /s/{spaceId}/api/alerting/rule/{ruleId}
Updates the attributes for a rule. (updateRule)
- You must have all
privileges for the appropriate Kibana features, depending on the consumer
and rule_type_id
of the rule you're updating. For example, you must have privileges for the Management > Stack rules feature, Analytics > Discover and Machine Learning features, Observability features, or Security features. If the rule has actions, you must also have read
privileges for the Management > Actions and Connectors feature. NOTE: This API supports only token-based authentication. When you update a rule, it identifies which roles you have at that point in time. Thereafter, when the rule performs queries, it uses those security privileges. If you have different privileges than the user that created or most recently updated the rule, you might change its behavior. Though some properties are optional, when you update the rule the existing property values are overwritten with default values. Therefore, it is recommended to explicitly set all property values.
+ To update a rule, you must have all
privileges for the appropriate Kibana features, depending on the consumer
and rule_type_id
of the rule you're updating. For example, you must have privileges for the Management > Stack rules feature, Analytics > Discover and Machine Learning features, Observability features, or Security features. If the rule has actions, you must also have read
privileges for the Management > Actions and Connectors feature. This API supports both key- and token-based authentication. To use key-based authentication, create an API key in Kibana and use it in the header of the API call. To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically. In both cases, the API key is subsequently used for authorization when the rule runs. NOTE: If the API key has different privileges than the key that created or most recently updated the rule, the rule behavior might change. Though some properties are optional, when you update the rule the existing property values are overwritten with default values. Therefore, it is recommended to explicitly set all property values.
Path parameters
diff --git a/docs/api/alerting/create_rule.asciidoc b/docs/api/alerting/create_rule.asciidoc
index c5e5bec9d061f..2bce4a1c49193 100644
--- a/docs/api/alerting/create_rule.asciidoc
+++ b/docs/api/alerting/create_rule.asciidoc
@@ -30,17 +30,6 @@ you must also have `read` privileges for the *Management* >
*{connectors-feature}* feature. For more details, refer to
<
>.
-=== {api-description-title}
-
-[WARNING]
-====
-* This API supports only
-<>.
-* When you create a rule, it identifies which roles you have at that point in time.
-Thereafter, when the rule performs queries, it uses those security privileges.
-If a user with different privileges updates the rule, its behavior might change.
-====
-
[[create-rule-api-path-params]]
=== {api-path-parms-title}
diff --git a/docs/api/alerting/update_rule.asciidoc b/docs/api/alerting/update_rule.asciidoc
index 0db4c2cf38195..11ca1dc35fc85 100644
--- a/docs/api/alerting/update_rule.asciidoc
+++ b/docs/api/alerting/update_rule.asciidoc
@@ -29,21 +29,6 @@ features, *{observability}*, or *Security* features. If the rule has
*{connectors-feature}* feature. For more details, refer to
<>.
-=== {api-description-title}
-
-[WARNING]
-====
-* This API supports only
-<>.
-* When you update a rule, it identifies which roles you have at that point in time.
-Thereafter, when the rule performs queries, it uses those security privileges.
-If you have different privileges than the user that created or most recently
-updated the rule, you might change its behavior.
-* Though some properties are optional, when you update the rule the existing
-property values are overwritten with default values. Therefore, it is
-recommended to explicitly set all property values.
-====
-
[[update-rule-api-path-params]]
=== {api-path-parms-title}
diff --git a/docs/user/alerting/alerting-setup.asciidoc b/docs/user/alerting/alerting-setup.asciidoc
index 0a2e35d0abceb..8987d2d3370a0 100644
--- a/docs/user/alerting/alerting-setup.asciidoc
+++ b/docs/user/alerting/alerting-setup.asciidoc
@@ -4,6 +4,11 @@
Set up
++++
+:frontmatter-description: Prerequisites and production considerations for using {kib} {alert-features}.
+:frontmatter-tags-products: [alerting]
+:frontmatter-tags-content-type: [other]
+:frontmatter-tags-user-goals: [configure]
+
{kib} {alert-features} are automatically enabled, but might require some additional
configuration.
@@ -77,27 +82,26 @@ A rule or connector created in one space will not be visible in another.
Rules are authorized using an API key.
Its credentials are used to run all background tasks associated with the rule, including condition checks like {es} queries and triggered actions.
-You can create API keys and use them in the header of your API calls as described in <>.
-If you create or edit a rule in {kib}, an API key is created that captures a snapshot of your privileges at the time of the edit. The following actions regenerate the API key in {kib}:
+If you create or edit a rule in {kib}, an API key is created that captures a snapshot of your privileges at the time of the edit.
+The following actions regenerate the API key in {kib}:
* Creating a rule
* Updating a rule
-When you disable a rule, it retains the associated API key which is reused when
-the rule is enabled. If the API key is missing when you enable the rule (for
-example, in the case of imported rules), it generates a new key that has your
-security privileges.
+When you disable a rule, it retains the associated API key which is reused when the rule is enabled.
+If the API key is missing when you enable the rule (for example, in the case of imported rules), it generates a new key that has your security privileges.
+
+You can update an API key manually in **{stack-manage-app} > {rules-ui}** or in the rule details page by selecting **Update API key** in the actions menu.
-You can update an API key manually in
-**{stack-manage-app} > {rules-ui}** or in the rule details page by selecting
-**Update API key** in the actions menu.
+If you manage your rules by using {kib} APIs, they support support both key- and token-based authentication as described in <>.
+To use key-based authentication, create API keys and use them in the header of your API calls as described in <>.
+To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically.
+In both cases, the API key is subsequently associated with the rule and used when it runs.
[IMPORTANT]
==============================================
-If a rule requires certain privileges, such as index privileges, to run and a
-user without those privileges updates the rule, the rule will no longer
-function. Conversely, if a user with greater or administrator privileges
-modifies the rule, it will begin running with increased privileges.
+If a rule requires certain privileges, such as index privileges, to run and a user without those privileges updates the rule, the rule will no longer function.
+Conversely, if a user with greater or administrator privileges modifies the rule, it will begin running with increased privileges.
The same behavior occurs when you change the API key in the header of your API calls.
==============================================
diff --git a/packages/content-management/tabbed_table_list_view/src/tabbed_table_list_view.tsx b/packages/content-management/tabbed_table_list_view/src/tabbed_table_list_view.tsx
index 9872e35d90c88..e1cd59f9a1378 100644
--- a/packages/content-management/tabbed_table_list_view/src/tabbed_table_list_view.tsx
+++ b/packages/content-management/tabbed_table_list_view/src/tabbed_table_list_view.tsx
@@ -47,23 +47,23 @@ export const TabbedTableListView = ({
[activeTabId, tabs]
);
+ const onFetchSuccess = useCallback(() => {
+ setHasInitialFetchReturned(true);
+ }, []);
+
const [tableList, setTableList] = useState(null);
useEffect(() => {
async function loadTableList() {
const newTableList = await getActiveTab().getTableList({
- onFetchSuccess: () => {
- if (!hasInitialFetchReturned) {
- setHasInitialFetchReturned(true);
- }
- },
+ onFetchSuccess,
setPageDataTestSubject,
});
setTableList(newTableList);
}
loadTableList();
- }, [hasInitialFetchReturned, activeTabId, tabs, getActiveTab]);
+ }, [activeTabId, tabs, getActiveTab, onFetchSuccess]);
return (
diff --git a/packages/content-management/table_list_view/src/table_list_view.tsx b/packages/content-management/table_list_view/src/table_list_view.tsx
index 71b08f82174bb..71e9f95bbf581 100644
--- a/packages/content-management/table_list_view/src/table_list_view.tsx
+++ b/packages/content-management/table_list_view/src/table_list_view.tsx
@@ -82,10 +82,8 @@ export const TableListView = ({
const [pageDataTestSubject, setPageDataTestSubject] = useState();
const onFetchSuccess = useCallback(() => {
- if (!hasInitialFetchReturned) {
- setHasInitialFetchReturned(true);
- }
- }, [hasInitialFetchReturned]);
+ setHasInitialFetchReturned(true);
+ }, []);
return (
diff --git a/packages/content-management/table_list_view_table/src/reducer.tsx b/packages/content-management/table_list_view_table/src/reducer.tsx
index c8486d92caced..0a8a89db80d92 100644
--- a/packages/content-management/table_list_view_table/src/reducer.tsx
+++ b/packages/content-management/table_list_view_table/src/reducer.tsx
@@ -39,11 +39,21 @@ export function getReducer() {
}
}
+ let hasNoItems = state.hasNoItems;
+
+ const hasQuery = state.searchQuery.text !== '';
+ if (hasQuery) {
+ hasNoItems = undefined;
+ } else {
+ hasNoItems = items.length === 0;
+ }
+
return {
...state,
hasInitialFetchReturned: true,
isFetchingItems: false,
items,
+ hasNoItems,
totalItems: action.data.response.total,
hasUpdatedAtMetadata,
tableSort: tableSort ?? state.tableSort,
diff --git a/packages/content-management/table_list_view_table/src/table_list_view.test.helpers.ts b/packages/content-management/table_list_view_table/src/table_list_view.test.helpers.ts
new file mode 100644
index 0000000000000..cbfa96198cc9d
--- /dev/null
+++ b/packages/content-management/table_list_view_table/src/table_list_view.test.helpers.ts
@@ -0,0 +1,64 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import type { TestBed } from '@kbn/test-jest-helpers';
+import { act } from 'react-dom/test-utils';
+
+export const getActions = ({ find, form, component }: TestBed) => {
+ /** Open the sort select drop down menu */
+ const openSortSelect = () => {
+ find('tableSortSelectBtn').at(0).simulate('click');
+ };
+
+ // --- Search Box ---
+
+ /** Set the search box value */
+ const updateSearchText = async (value: string) => {
+ await act(async () => {
+ find('tableListSearchBox').simulate('keyup', {
+ key: 'Enter',
+ target: { value },
+ });
+ });
+ component.update();
+ };
+
+ /** Get the Search box value */
+ const getSearchBoxValue = () => find('tableListSearchBox').props().defaultValue;
+
+ // --- Row Actions ---
+ const selectRow = (rowId: string) => {
+ act(() => {
+ form.selectCheckBox(`checkboxSelectRow-${rowId}`);
+ });
+ component.update();
+ };
+
+ const clickDeleteSelectedItemsButton = () => {
+ act(() => {
+ find('deleteSelectedItems').simulate('click');
+ });
+ component.update();
+ };
+
+ const clickConfirmModalButton = async () => {
+ await act(async () => {
+ find('confirmModalConfirmButton').simulate('click');
+ });
+ component.update();
+ };
+
+ return {
+ openSortSelect,
+ updateSearchText,
+ getSearchBoxValue,
+ selectRow,
+ clickDeleteSelectedItemsButton,
+ clickConfirmModalButton,
+ };
+};
diff --git a/packages/content-management/table_list_view_table/src/table_list_view.test.tsx b/packages/content-management/table_list_view_table/src/table_list_view.test.tsx
index 0fc1840f26613..94c1ca5ab6753 100644
--- a/packages/content-management/table_list_view_table/src/table_list_view.test.tsx
+++ b/packages/content-management/table_list_view_table/src/table_list_view.test.tsx
@@ -22,6 +22,7 @@ import {
type TableListViewTableProps,
type UserContentCommonSchema,
} from './table_list_view_table';
+import { getActions } from './table_list_view.test.helpers';
const mockUseEffect = useEffect;
@@ -54,12 +55,6 @@ const twoDaysAgoToString = new Date(twoDaysAgo.getTime()).toDateString();
const yesterday = new Date(new Date().setDate(new Date().getDate() - 1));
const yesterdayToString = new Date(yesterday.getTime()).toDateString();
-const getActions = (testBed: TestBed) => ({
- openSortSelect() {
- testBed.find('tableSortSelectBtn').at(0).simulate('click');
- },
-});
-
describe('TableListView', () => {
const requiredProps: TableListViewTableProps = {
entityName: 'test',
@@ -91,50 +86,102 @@ describe('TableListView', () => {
}
);
- test('render default empty prompt', async () => {
- let testBed: TestBed;
+ describe('empty prompt', () => {
+ test('render default empty prompt', async () => {
+ let testBed: TestBed;
- await act(async () => {
- testBed = await setup();
+ await act(async () => {
+ testBed = await setup();
+ });
+
+ const { component, exists } = testBed!;
+ component.update();
+
+ expect(component.find(EuiEmptyPrompt).length).toBe(1);
+ expect(exists('newItemButton')).toBe(false);
});
- const { component, exists } = testBed!;
- component.update();
+ // avoid trapping users in empty prompt that can not create new items
+ test('render default empty prompt with create action when createItem supplied', async () => {
+ let testBed: TestBed;
- expect(component.find(EuiEmptyPrompt).length).toBe(1);
- expect(exists('newItemButton')).toBe(false);
- });
+ await act(async () => {
+ testBed = await setup({ createItem: () => undefined });
+ });
- // avoid trapping users in empty prompt that can not create new items
- test('render default empty prompt with create action when createItem supplied', async () => {
- let testBed: TestBed;
+ const { component, exists } = testBed!;
+ component.update();
- await act(async () => {
- testBed = await setup({ createItem: () => undefined });
+ expect(component.find(EuiEmptyPrompt).length).toBe(1);
+ expect(exists('newItemButton')).toBe(true);
});
- const { component, exists } = testBed!;
- component.update();
+ test('render custom empty prompt', async () => {
+ let testBed: TestBed;
- expect(component.find(EuiEmptyPrompt).length).toBe(1);
- expect(exists('newItemButton')).toBe(true);
- });
+ const CustomEmptyPrompt = () => {
+ return Table empty} />;
+ };
- test('render custom empty prompt', async () => {
- let testBed: TestBed;
+ await act(async () => {
+ testBed = await setup({ emptyPrompt: });
+ });
- const CustomEmptyPrompt = () => {
- return Table empty} />;
- };
+ const { component, exists } = testBed!;
+ component.update();
- await act(async () => {
- testBed = await setup({ emptyPrompt: });
+ expect(exists('custom-empty-prompt')).toBe(true);
});
- const { component, exists } = testBed!;
- component.update();
+ test('render empty prompt after deleting all items from table', async () => {
+ // NOTE: this test is using helpers that are being tested in the
+ // "should allow select items to be deleted" test below.
+ // If this test fails, check that one first.
+
+ const hits: UserContentCommonSchema[] = [
+ {
+ id: 'item-1',
+ type: 'dashboard',
+ updatedAt: '2020-01-01T00:00:00Z',
+ attributes: {
+ title: 'Item 1',
+ },
+ references: [],
+ },
+ ];
- expect(exists('custom-empty-prompt')).toBe(true);
+ const findItems = jest.fn().mockResolvedValue({ total: 1, hits });
+ const deleteItems = jest.fn();
+
+ let testBed: TestBed;
+
+ const EmptyPrompt = () => {
+ return Table empty} />;
+ };
+
+ await act(async () => {
+ testBed = await setup({ emptyPrompt: , findItems, deleteItems });
+ });
+
+ const { component, exists, table } = testBed!;
+ const { selectRow, clickConfirmModalButton, clickDeleteSelectedItemsButton } = getActions(
+ testBed!
+ );
+ component.update();
+
+ expect(exists('custom-empty-prompt')).toBe(false);
+ const { tableCellsValues } = table.getMetaData('itemsInMemTable');
+ const [row] = tableCellsValues;
+ expect(row[1]).toBe('Item 1'); // Note: row[0] is the checkbox
+
+ // We delete the item in the table and expect the empty prompt to show
+ findItems.mockResolvedValue({ total: 0, hits: [] });
+ selectRow('item-1');
+ clickDeleteSelectedItemsButton();
+ await clickConfirmModalButton();
+
+ expect(exists('custom-empty-prompt')).toBe(true);
+ });
});
describe('default columns', () => {
@@ -798,7 +845,20 @@ describe('TableListView', () => {
let testBed: TestBed;
const initialFilter = 'tag:(tag-1)';
- const findItems = jest.fn().mockResolvedValue({ total: 0, hits: [] });
+ const findItems = jest.fn().mockResolvedValue({
+ total: 1,
+ hits: [
+ {
+ id: 'item-1',
+ type: 'dashboard',
+ updatedAt: new Date('2023-07-15').toISOString(),
+ attributes: {
+ title: 'Item 1',
+ },
+ references: [],
+ },
+ ],
+ });
await act(async () => {
testBed = await setupInitialFilter({
@@ -824,6 +884,173 @@ describe('TableListView', () => {
});
});
+ describe('search', () => {
+ const updatedAt = new Date('2023-07-15').toISOString();
+
+ const hits: UserContentCommonSchema[] = [
+ {
+ id: 'item-1',
+ type: 'dashboard',
+ updatedAt,
+ attributes: {
+ title: 'Item 1',
+ },
+ references: [],
+ },
+ {
+ id: 'item-2',
+ type: 'dashboard',
+ updatedAt,
+ attributes: {
+ title: 'Item 2',
+ },
+ references: [],
+ },
+ ];
+
+ const findItems = jest.fn();
+
+ const setupSearch = (...args: Parameters>) => {
+ const testBed = registerTestBed(
+ WithServices(TableListViewTable),
+ {
+ defaultProps: {
+ ...requiredProps,
+ findItems,
+ urlStateEnabled: false,
+ entityName: 'Foo',
+ entityNamePlural: 'Foos',
+ },
+ memoryRouter: { wrapComponent: true },
+ }
+ )(...args);
+
+ const { updateSearchText, getSearchBoxValue } = getActions(testBed);
+
+ return {
+ testBed,
+ updateSearchText,
+ getSearchBoxValue,
+ getLastCallArgsFromFindItems: () => findItems.mock.calls[findItems.mock.calls.length - 1],
+ };
+ };
+
+ beforeEach(() => {
+ findItems.mockReset().mockResolvedValue({ total: hits.length, hits });
+ });
+
+ test('should search the table items', async () => {
+ let testBed: TestBed;
+ let updateSearchText: (value: string) => Promise;
+ let getLastCallArgsFromFindItems: () => Parameters;
+ let getSearchBoxValue: () => string;
+
+ await act(async () => {
+ ({ testBed, getLastCallArgsFromFindItems, getSearchBoxValue, updateSearchText } =
+ await setupSearch());
+ });
+
+ const { component, table } = testBed!;
+ component.update();
+
+ let searchTerm = '';
+ let expected = '';
+ [searchTerm] = getLastCallArgsFromFindItems!();
+ expect(getSearchBoxValue!()).toBe(expected);
+ expect(searchTerm).toBe(expected);
+
+ const { tableCellsValues } = table.getMetaData('itemsInMemTable');
+ expect(tableCellsValues).toMatchInlineSnapshot(`
+ Array [
+ Array [
+ "Item 1",
+ "Sat Jul 15 2023",
+ ],
+ Array [
+ "Item 2",
+ "Sat Jul 15 2023",
+ ],
+ ]
+ `);
+
+ findItems.mockResolvedValueOnce({
+ total: 1,
+ hits: [
+ {
+ id: 'item-from-search',
+ type: 'dashboard',
+ updatedAt: new Date('2023-07-01').toISOString(),
+ attributes: {
+ title: 'Item from search',
+ },
+ references: [],
+ },
+ ],
+ });
+
+ expected = 'foo';
+ await updateSearchText!(expected);
+ [searchTerm] = getLastCallArgsFromFindItems!();
+ expect(getSearchBoxValue!()).toBe(expected);
+ expect(searchTerm).toBe(expected);
+
+ expect(table.getMetaData('itemsInMemTable').tableCellsValues).toMatchInlineSnapshot(`
+ Array [
+ Array [
+ "Item from search",
+ "July 1, 2023",
+ ],
+ ]
+ `);
+ });
+
+ test('should search and render empty list if no result', async () => {
+ let testBed: TestBed;
+ let updateSearchText: (value: string) => Promise;
+
+ await act(async () => {
+ ({ testBed, updateSearchText } = await setupSearch());
+ });
+
+ const { component, table, find } = testBed!;
+ component.update();
+
+ findItems.mockResolvedValueOnce({
+ total: 0,
+ hits: [],
+ });
+
+ await updateSearchText!('unknown items');
+
+ expect(table.getMetaData('itemsInMemTable').tableCellsValues).toMatchInlineSnapshot(`
+ Array [
+ Array [
+ "No Foos matched your search.",
+ ],
+ ]
+ `);
+
+ await act(async () => {
+ find('clearSearchButton').simulate('click');
+ });
+ component.update();
+
+ // We should get back the initial 2 items (Item 1 and Item 2)
+ expect(table.getMetaData('itemsInMemTable').tableCellsValues).toMatchInlineSnapshot(`
+ Array [
+ Array [
+ "Item 1",
+ "Sat Jul 15 2023",
+ ],
+ Array [
+ "Item 2",
+ "Sat Jul 15 2023",
+ ],
+ ]
+ `);
+ });
+ });
+
describe('url state', () => {
let router: Router | undefined;
@@ -1153,10 +1380,11 @@ describe('TableListView', () => {
};
test('should allow select items to be deleted', async () => {
- const {
- testBed: { table, find, exists, component, form },
- deleteItems,
- } = await setupTest();
+ const { testBed, deleteItems } = await setupTest();
+
+ const { table, exists, component } = testBed;
+ const { selectRow, clickDeleteSelectedItemsButton, clickConfirmModalButton } =
+ getActions(testBed);
const { tableCellsValues } = table.getMetaData('itemsInMemTable');
@@ -1165,28 +1393,21 @@ describe('TableListView', () => {
['', 'Item 1Item 1 description', twoDaysAgoToString],
]);
+ // Select the second item
const selectedHit = hits[1];
expect(exists('deleteSelectedItems')).toBe(false);
- act(() => {
- // Select the second item
- form.selectCheckBox(`checkboxSelectRow-${selectedHit.id}`);
- });
- component.update();
+
+ selectRow(selectedHit.id);
// Delete button is now visible
expect(exists('deleteSelectedItems')).toBe(true);
// Click delete and validate that confirm modal opens
expect(component.exists('.euiModal--confirmation')).toBe(false);
- act(() => {
- find('deleteSelectedItems').simulate('click');
- });
- component.update();
+ clickDeleteSelectedItemsButton();
expect(component.exists('.euiModal--confirmation')).toBe(true);
- await act(async () => {
- find('confirmModalConfirmButton').simulate('click');
- });
+ await clickConfirmModalButton();
expect(deleteItems).toHaveBeenCalledWith([selectedHit]);
});
diff --git a/packages/content-management/table_list_view_table/src/table_list_view_table.tsx b/packages/content-management/table_list_view_table/src/table_list_view_table.tsx
index 33ef91dc65e4b..9d7613c6a122d 100644
--- a/packages/content-management/table_list_view_table/src/table_list_view_table.tsx
+++ b/packages/content-management/table_list_view_table/src/table_list_view_table.tsx
@@ -108,6 +108,7 @@ export interface TableListViewTableProps<
contentEditor?: ContentEditorConfig;
tableCaption: string;
+ /** Flag to force a new fetch of the table items. Whenever it changes, the `findItems()` will be called. */
refreshListBouncer?: boolean;
onFetchSuccess: () => void;
setPageDataTestSubject: (subject: string) => void;
@@ -115,6 +116,12 @@ export interface TableListViewTableProps<
export interface State {
items: T[];
+ /**
+ * Flag to indicate if there aren't any item when **no filteres are applied**.
+ * When there are no item we render an empty prompt.
+ * Default to `undefined` to indicate that we don't know yet if there are items or not.
+ */
+ hasNoItems: boolean | undefined;
hasInitialFetchReturned: boolean;
isFetchingItems: boolean;
isDeletingItems: boolean;
@@ -293,6 +300,7 @@ function TableListViewTableComp({
const isMounted = useRef(false);
const fetchIdx = useRef(0);
+
/**
* The "onTableSearchChange()" handler has an async behavior. We want to be able to discard
* previsous search changes and only handle the last one. For that we keep a counter of the changes.
@@ -335,9 +343,10 @@ function TableListViewTableComp({
const initialState = useMemo>(
() => ({
items: [],
+ hasNoItems: undefined,
totalItems: 0,
hasInitialFetchReturned: false,
- isFetchingItems: false,
+ isFetchingItems: true,
isDeletingItems: false,
showDeleteModal: false,
hasUpdatedAtMetadata: false,
@@ -364,6 +373,7 @@ function TableListViewTableComp({
hasInitialFetchReturned,
isFetchingItems,
items,
+ hasNoItems,
fetchError,
showDeleteModal,
isDeletingItems,
@@ -374,8 +384,6 @@ function TableListViewTableComp({
tableSort,
} = state;
- const hasQuery = searchQuery.text !== '';
- const hasNoItems = hasInitialFetchReturned && items.length === 0 && !hasQuery;
const showFetchError = Boolean(fetchError);
const showLimitError = !showFetchError && totalItems > listingLimit;
@@ -857,17 +865,7 @@ function TableListViewTableComp({
// ------------
// Effects
// ------------
- useDebounce(
- () => {
- // Do not call fetchItems on dependency changes when initial fetch does not load any items
- // to avoid flashing between empty table and no items view
- if (!hasNoItems) {
- fetchItems();
- }
- },
- 300,
- [fetchItems, refreshListBouncer]
- );
+ useDebounce(fetchItems, 300, [fetchItems, refreshListBouncer]);
useEffect(() => {
if (!urlStateEnabled) {
diff --git a/packages/core/elasticsearch/core-elasticsearch-client-server-internal/src/get_ecs_response_log.test.ts b/packages/core/elasticsearch/core-elasticsearch-client-server-internal/src/get_ecs_response_log.test.ts
index 03c8c118edcf2..af9470d18e892 100644
--- a/packages/core/elasticsearch/core-elasticsearch-client-server-internal/src/get_ecs_response_log.test.ts
+++ b/packages/core/elasticsearch/core-elasticsearch-client-server-internal/src/get_ecs_response_log.test.ts
@@ -91,6 +91,23 @@ describe('getEcsResponseLog', () => {
`);
});
+ test('redacts es-client-authentication headers by default', () => {
+ const event = createResponseEvent({
+ requestParams: {
+ headers: { 'es-client-authentication': 'ae3fda37-xxx', 'user-agent': 'world' },
+ },
+ response: { headers: { 'content-length': '123' } },
+ });
+ const log = getEcsResponseLog(event);
+ // @ts-expect-error ECS custom field
+ expect(log.http.request.headers).toMatchInlineSnapshot(`
+ Object {
+ "es-client-authentication": "[REDACTED]",
+ "user-agent": "world",
+ }
+ `);
+ });
+
test('does not mutate original headers', () => {
const reqHeaders = { a: 'foo', b: ['hello', 'world'] };
const resHeaders = { c: 'bar' };
diff --git a/packages/core/elasticsearch/core-elasticsearch-client-server-internal/src/get_ecs_response_log.ts b/packages/core/elasticsearch/core-elasticsearch-client-server-internal/src/get_ecs_response_log.ts
index fa122166ada08..6b44c48925438 100644
--- a/packages/core/elasticsearch/core-elasticsearch-client-server-internal/src/get_ecs_response_log.ts
+++ b/packages/core/elasticsearch/core-elasticsearch-client-server-internal/src/get_ecs_response_log.ts
@@ -12,7 +12,13 @@ import { type LogMeta } from '@kbn/logging';
// If you are updating these, consider whether they should also be updated in the
// http service `getResponseLog`
-const FORBIDDEN_HEADERS = ['authorization', 'cookie', 'set-cookie', 'x-elastic-app-auth'];
+const FORBIDDEN_HEADERS = [
+ 'authorization',
+ 'cookie',
+ 'set-cookie',
+ 'x-elastic-app-auth',
+ 'es-client-authentication',
+];
const REDACTED_HEADER_TEXT = '[REDACTED]';
// We are excluding sensitive headers by default, until we have a log filtering mechanism.
diff --git a/packages/core/http/core-http-server-internal/src/logging/get_response_log.test.ts b/packages/core/http/core-http-server-internal/src/logging/get_response_log.test.ts
index a8f607c5c6865..a77283b6575ff 100644
--- a/packages/core/http/core-http-server-internal/src/logging/get_response_log.test.ts
+++ b/packages/core/http/core-http-server-internal/src/logging/get_response_log.test.ts
@@ -211,6 +211,21 @@ describe('getEcsResponseLog', () => {
`);
});
+ test('redacts es-client-authentication headers by default', () => {
+ const req = createMockHapiRequest({
+ headers: { 'es-client-authentication': 'ae3fda37-xxx', 'user-agent': 'world' },
+ response: { headers: { 'content-length': '123' } },
+ });
+ const result = getEcsResponseLog(req, logger);
+ // @ts-expect-error ECS custom field
+ expect(result.meta.http.request.headers).toMatchInlineSnapshot(`
+ Object {
+ "es-client-authentication": "[REDACTED]",
+ "user-agent": "world",
+ }
+ `);
+ });
+
test('does not mutate original headers', () => {
const reqHeaders = { a: 'foo', b: ['hello', 'world'] };
const resHeaders = { headers: { c: 'bar' } };
diff --git a/packages/core/http/core-http-server-internal/src/logging/get_response_log.ts b/packages/core/http/core-http-server-internal/src/logging/get_response_log.ts
index f356bf077095a..2cc9c50a1b319 100644
--- a/packages/core/http/core-http-server-internal/src/logging/get_response_log.ts
+++ b/packages/core/http/core-http-server-internal/src/logging/get_response_log.ts
@@ -16,7 +16,13 @@ import { getResponsePayloadBytes } from './get_payload_size';
// If you are updating these, consider whether they should also be updated in the
// elasticsearch service `getEcsResponseLog`
-const FORBIDDEN_HEADERS = ['authorization', 'cookie', 'set-cookie', 'x-elastic-app-auth'];
+const FORBIDDEN_HEADERS = [
+ 'authorization',
+ 'cookie',
+ 'set-cookie',
+ 'x-elastic-app-auth',
+ 'es-client-authentication',
+];
const REDACTED_HEADER_TEXT = '[REDACTED]';
type HapiHeaders = Record;
diff --git a/src/plugins/event_annotation/public/components/table_list.tsx b/src/plugins/event_annotation/public/components/table_list.tsx
index afc94b11e8fc6..2e172c4a9daed 100644
--- a/src/plugins/event_annotation/public/components/table_list.tsx
+++ b/src/plugins/event_annotation/public/components/table_list.tsx
@@ -77,8 +77,8 @@ export const EventAnnotationGroupTableList = ({
const [refreshListBouncer, setRefreshListBouncer] = useState(false);
const refreshList = useCallback(() => {
- setRefreshListBouncer(!refreshListBouncer);
- }, [refreshListBouncer]);
+ setRefreshListBouncer((prev) => !prev);
+ }, []);
const fetchItems = useCallback(
(
diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json
index 1347fb55897ff..5a79e7cb384e3 100644
--- a/src/plugins/telemetry/schema/oss_plugins.json
+++ b/src/plugins/telemetry/schema/oss_plugins.json
@@ -8938,6 +8938,12 @@
"description": "Default value of the setting was changed."
}
},
+ "securitySolution:alertTags": {
+ "type": "keyword",
+ "_meta": {
+ "description": "Default value of the setting was changed."
+ }
+ },
"securitySolution:newsFeedUrl": {
"type": "keyword",
"_meta": {
@@ -9076,12 +9082,6 @@
"description": "Non-default value of setting."
}
},
- "securitySolution:alertTags": {
- "type": "keyword",
- "_meta": {
- "description": "Default value of the setting was changed."
- }
- },
"search:includeFrozen": {
"type": "boolean",
"_meta": {
diff --git a/src/plugins/visualizations/common/content_management/v1/cm_services.ts b/src/plugins/visualizations/common/content_management/v1/cm_services.ts
index 62ae0afc97830..4b1165d357203 100644
--- a/src/plugins/visualizations/common/content_management/v1/cm_services.ts
+++ b/src/plugins/visualizations/common/content_management/v1/cm_services.ts
@@ -29,7 +29,7 @@ const referencesSchema = schema.arrayOf(referenceSchema);
const visualizeAttributesSchema = schema.object(
{
title: schema.string(),
- description: schema.maybe(schema.string()),
+ description: schema.maybe(schema.nullable(schema.string())),
version: schema.maybe(schema.number()),
kibanaSavedObjectMeta: schema.maybe(schema.object({ searchSourceJSON: schema.string() })),
uiStateJSON: schema.maybe(schema.string()),
diff --git a/test/functional/apps/dashboard/group1/embeddable_rendering.ts b/test/functional/apps/dashboard/group1/embeddable_rendering.ts
index 93b111f072443..d7addf89ac404 100644
--- a/test/functional/apps/dashboard/group1/embeddable_rendering.ts
+++ b/test/functional/apps/dashboard/group1/embeddable_rendering.ts
@@ -102,6 +102,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// FLAKY: https://github.com/elastic/kibana/issues/158529
describe.skip('dashboard embeddable rendering', function describeIndexTests() {
+ const from = 'Jan 1, 2018 @ 00:00:00.000';
+ const to = 'Apr 13, 2018 @ 00:00:00.000';
before(async () => {
await security.testUser.setRoles(['kibana_admin', 'animals', 'test_logstash_reader']);
await kibanaServer.savedObjects.cleanStandardList();
@@ -111,14 +113,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await kibanaServer.uiSettings.replace({
defaultIndex: '0bf35f60-3dc9-11e8-8660-4d65aa086b3c',
});
+ await PageObjects.common.setTime({ from, to });
await PageObjects.common.navigateToApp('dashboard');
await PageObjects.dashboard.preserveCrossAppState();
await PageObjects.dashboard.clickNewDashboard();
await elasticChart.setNewChartUiDebugFlag(true);
-
- const fromTime = 'Jan 1, 2018 @ 00:00:00.000';
- const toTime = 'Apr 13, 2018 @ 00:00:00.000';
- await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime);
});
after(async () => {
@@ -127,6 +126,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const newUrl = currentUrl.replace(/\?.*$/, '');
await browser.get(newUrl, false);
await security.testUser.restoreDefaults();
+ await PageObjects.common.unsetTime();
await kibanaServer.savedObjects.cleanStandardList();
});
diff --git a/test/functional/apps/dashboard/group5/share.ts b/test/functional/apps/dashboard/group5/share.ts
index b6a2e9811e51f..a6d9289313e62 100644
--- a/test/functional/apps/dashboard/group5/share.ts
+++ b/test/functional/apps/dashboard/group5/share.ts
@@ -106,19 +106,19 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await kibanaServer.uiSettings.replace({
defaultIndex: '0bf35f60-3dc9-11e8-8660-4d65aa086b3c',
});
+ const from = 'Sep 19, 2017 @ 06:31:44.000';
+ const to = 'Sep 23, 2018 @ 18:31:44.000';
+ await PageObjects.common.setTime({ from, to });
await PageObjects.common.navigateToApp('dashboard');
await PageObjects.dashboard.preserveCrossAppState();
await PageObjects.dashboard.loadSavedDashboard('few panels');
-
await PageObjects.dashboard.switchToEditMode();
- const from = 'Sep 19, 2017 @ 06:31:44.000';
- const to = 'Sep 23, 2018 @ 18:31:44.000';
- await PageObjects.timePicker.setAbsoluteRange(from, to);
await PageObjects.dashboard.waitForRenderComplete();
});
after(async () => {
await kibanaServer.savedObjects.cleanStandardList();
+ await PageObjects.common.unsetTime();
});
describe('snapshot share', async () => {
diff --git a/test/functional/apps/dashboard_elements/controls/common/range_slider.ts b/test/functional/apps/dashboard_elements/controls/common/range_slider.ts
index d6cd7388987fe..9140c23573c3f 100644
--- a/test/functional/apps/dashboard_elements/controls/common/range_slider.ts
+++ b/test/functional/apps/dashboard_elements/controls/common/range_slider.ts
@@ -19,9 +19,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const filterBar = getService('filterBar');
const testSubjects = getService('testSubjects');
const kibanaServer = getService('kibanaServer');
- const { dashboardControls, timePicker, common, dashboard, header } = getPageObjects([
+ const { dashboardControls, common, dashboard, header } = getPageObjects([
'dashboardControls',
- 'timePicker',
'dashboard',
'common',
'header',
@@ -46,16 +45,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await kibanaServer.uiSettings.replace({
defaultIndex: '0bf35f60-3dc9-11e8-8660-4d65aa086b3c',
});
+ await common.setTime({
+ from: 'Oct 22, 2018 @ 00:00:00.000',
+ to: 'Dec 3, 2018 @ 00:00:00.000',
+ });
await common.navigateToApp('dashboard');
await dashboardControls.enableControlsLab();
await common.navigateToApp('dashboard');
await dashboard.preserveCrossAppState();
await dashboard.gotoDashboardLandingPage();
await dashboard.clickNewDashboard();
- await timePicker.setAbsoluteRange(
- 'Oct 22, 2018 @ 00:00:00.000',
- 'Dec 3, 2018 @ 00:00:00.000'
- );
await dashboard.saveDashboard(DASHBOARD_NAME, { exitFromEditMode: false });
});
@@ -66,6 +65,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
);
await esArchiver.unload('test/functional/fixtures/es_archiver/kibana_sample_data_flights');
await kibanaServer.uiSettings.unset('defaultIndex');
+ await common.unsetTime();
await security.testUser.restoreDefaults();
});
diff --git a/test/functional/apps/discover/embeddable/_saved_search_embeddable.ts b/test/functional/apps/discover/embeddable/_saved_search_embeddable.ts
index 1bfdc9143ad4c..8961af57a4ad2 100644
--- a/test/functional/apps/discover/embeddable/_saved_search_embeddable.ts
+++ b/test/functional/apps/discover/embeddable/_saved_search_embeddable.ts
@@ -32,10 +32,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await kibanaServer.uiSettings.replace({
defaultIndex: '0bf35f60-3dc9-11e8-8660-4d65aa086b3c',
});
+ await PageObjects.common.setTime({
+ from: 'Sep 22, 2015 @ 00:00:00.000',
+ to: 'Sep 23, 2015 @ 00:00:00.000',
+ });
});
after(async () => {
await kibanaServer.savedObjects.cleanStandardList();
+ await PageObjects.common.unsetTime();
});
beforeEach(async () => {
@@ -43,10 +48,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await filterBar.ensureFieldEditorModalIsClosed();
await PageObjects.dashboard.gotoDashboardLandingPage();
await PageObjects.dashboard.clickNewDashboard();
- await PageObjects.timePicker.setAbsoluteRange(
- 'Sep 22, 2015 @ 00:00:00.000',
- 'Sep 23, 2015 @ 00:00:00.000'
- );
});
const addSearchEmbeddableToDashboard = async () => {
diff --git a/test/functional/apps/management/_files.ts b/test/functional/apps/management/_files.ts
index 54b22028275d7..deebdb18f374b 100644
--- a/test/functional/apps/management/_files.ts
+++ b/test/functional/apps/management/_files.ts
@@ -13,8 +13,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
const PageObjects = getPageObjects(['common', 'filesManagement']);
const testSubjects = getService('testSubjects');
- // FLAKY: https://github.com/elastic/kibana/issues/160178
- describe.skip('Files management', () => {
+ describe('Files management', () => {
before(async () => {
await PageObjects.filesManagement.navigateTo();
});
diff --git a/test/functional/apps/visualize/group3/_linked_saved_searches.ts b/test/functional/apps/visualize/group3/_linked_saved_searches.ts
index c27d5725e50ac..f97a4c86e4560 100644
--- a/test/functional/apps/visualize/group3/_linked_saved_searches.ts
+++ b/test/functional/apps/visualize/group3/_linked_saved_searches.ts
@@ -31,19 +31,22 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
before(async () => {
await PageObjects.visualize.initTests();
+ await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings();
await PageObjects.common.navigateToApp('discover');
- await PageObjects.timePicker.setDefaultAbsoluteRange();
await filterBar.addFilter({ field: 'extension.raw', operation: 'is', value: 'jpg' });
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.saveSearch(savedSearchName);
discoverSavedSearchUrlPath = (await browser.getCurrentUrl()).split('?')[0];
});
+ after(async () => {
+ await PageObjects.common.unsetTime();
+ });
+
it('should create a visualization from a saved search', async () => {
await PageObjects.visualize.navigateToNewAggBasedVisualization();
await PageObjects.visualize.clickDataTable();
await PageObjects.visualize.clickSavedSearch(savedSearchName);
- await PageObjects.timePicker.setDefaultAbsoluteRange();
await retry.waitFor('wait for count to equal 9,109', async () => {
const data = await PageObjects.visChart.getTableVisContent();
return data[0][0] === '9,109';
diff --git a/test/functional/apps/visualize/group6/_tsvb_markdown.ts b/test/functional/apps/visualize/group6/_tsvb_markdown.ts
index 9f259ff005364..f015a0a010748 100644
--- a/test/functional/apps/visualize/group6/_tsvb_markdown.ts
+++ b/test/functional/apps/visualize/group6/_tsvb_markdown.ts
@@ -11,9 +11,9 @@ import expect from '@kbn/expect';
import { FtrProviderContext } from '../../../ftr_provider_context';
export default function ({ getPageObjects, getService }: FtrProviderContext) {
- const { visualBuilder, timePicker, visualize, visChart } = getPageObjects([
+ const { visualBuilder, common, visualize, visChart } = getPageObjects([
'visualBuilder',
- 'timePicker',
+ 'common',
'visualize',
'visChart',
]);
@@ -37,20 +37,24 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
describe('markdown', () => {
before(async () => {
await visualize.initTests();
+ await common.setTime({
+ to: 'Sep 22, 2015 @ 06:00:00.000',
+ from: 'Sep 22, 2015 @ 11:00:00.000',
+ });
await visualize.navigateToNewVisualization();
await visualize.clickVisualBuilder();
await visualBuilder.checkVisualBuilderIsPresent();
await visualBuilder.clickMarkdown();
- await timePicker.setAbsoluteRange(
- 'Sep 22, 2015 @ 06:00:00.000',
- 'Sep 22, 2015 @ 11:00:00.000'
- );
await visualBuilder.markdownSwitchSubTab('options');
await visualBuilder.setMetricsDataTimerangeMode('Last value');
await visualBuilder.setDropLastBucket(true);
await visualBuilder.markdownSwitchSubTab('markdown');
});
+ after(async () => {
+ await common.unsetTime();
+ });
+
it('should render subtabs and table variables markdown components', async () => {
const tabs = await visualBuilder.getSubTabs();
expect(tabs).to.have.length(3);
diff --git a/x-pack/plugins/alerting/docs/openapi/bundled.json b/x-pack/plugins/alerting/docs/openapi/bundled.json
index d97cc6d892a61..1131daa58f3c0 100644
--- a/x-pack/plugins/alerting/docs/openapi/bundled.json
+++ b/x-pack/plugins/alerting/docs/openapi/bundled.json
@@ -29,7 +29,7 @@
"post": {
"summary": "Creates a rule with a randomly generated rule identifier.",
"operationId": "createRule",
- "description": "You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're creating. For example, you must have privileges for the **Management > Stack rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. NOTE: This API supports only token-based authentication. When you create a rule, it identifies which roles you have at that point in time. Thereafter, when the rule performs queries, it uses those security privileges. If a user with different privileges updates the rule, its behavior might change.\n",
+ "description": "To create a rule, you must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're creating. For example, you must have privileges for the **Management > Stack rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. This API supports both key- and token-based authentication. To use key-based authentication, create an API key in Kibana and use it in the header of the API call. To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically. In both cases, the API key is subsequently used for authorization when the rule runs.\n",
"tags": [
"alerting"
],
@@ -167,7 +167,7 @@
"delete": {
"summary": "Deletes a rule.",
"operationId": "deleteRule",
- "description": "You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're deleting. For example, the **Management** > **Stack Rules** feature, **Analytics** > **Discover** or **Machine Learning** features, **Observability**, or **Security** features. WARNING: After you delete a rule, you cannot recover it.\n",
+ "description": "To delete a rule, you must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're deleting. For example, the **Management** > **Stack Rules** feature, **Analytics** > **Discover** or **Machine Learning** features, **Observability**, or **Security** features. WARNING: After you delete a rule, you cannot recover it. If the API key that is used by the rule was created automatically, it is deleted.\n",
"tags": [
"alerting"
],
@@ -216,7 +216,7 @@
"post": {
"summary": "Creates a rule with a specific rule identifier.",
"operationId": "createRuleId",
- "description": "You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're creating. For example, you must have privileges for the **Management > Stack rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. NOTE: This API supports only token-based authentication. When you create a rule, it identifies which roles you have at that point in time. Thereafter, when the rule performs queries, it uses those security privileges. If a user with different privileges updates the rule, its behavior might change.\n",
+ "description": "To create a rule, you must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're creating. For example, you must have privileges for the **Management > Stack rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. This API supports both key- and token-based authentication. To use key-based authentication, create an API key in Kibana and use it in the header of the API call. To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically. In both cases, the API key is subsequently used for authorization when the rule runs.\n",
"tags": [
"alerting"
],
@@ -299,7 +299,7 @@
"put": {
"summary": "Updates the attributes for a rule.",
"operationId": "updateRule",
- "description": "You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're updating. For example, you must have privileges for the **Management > Stack rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. NOTE: This API supports only token-based authentication. When you update a rule, it identifies which roles you have at that point in time. Thereafter, when the rule performs queries, it uses those security privileges. If you have different privileges than the user that created or most recently updated the rule, you might change its behavior. Though some properties are optional, when you update the rule the existing property values are overwritten with default values. Therefore, it is recommended to explicitly set all property values.\n",
+ "description": "To update a rule, you must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're updating. For example, you must have privileges for the **Management > Stack rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. This API supports both key- and token-based authentication. To use key-based authentication, create an API key in Kibana and use it in the header of the API call. To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically. In both cases, the API key is subsequently used for authorization when the rule runs. NOTE: If the API key has different privileges than the key that created or most recently updated the rule, the rule behavior might change. Though some properties are optional, when you update the rule the existing property values are overwritten with default values. Therefore, it is recommended to explicitly set all property values.\n",
"tags": [
"alerting"
],
@@ -438,7 +438,7 @@
"post": {
"summary": "Enables a rule.",
"operationId": "enableRule",
- "description": "This API supports token-based authentication only. You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features.\n",
+ "description": "To enable a rule, you must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features. This API supports both key- and token-based authentication. To use key-based authentication, create an API key in Kibana and use it in the header of the API call. To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically. In both cases, the API key is subsequently used for authorization when the rule runs.\n",
"tags": [
"alerting"
],
diff --git a/x-pack/plugins/alerting/docs/openapi/bundled.yaml b/x-pack/plugins/alerting/docs/openapi/bundled.yaml
index a6c019625937b..18b92843bd09f 100644
--- a/x-pack/plugins/alerting/docs/openapi/bundled.yaml
+++ b/x-pack/plugins/alerting/docs/openapi/bundled.yaml
@@ -20,7 +20,7 @@ paths:
summary: Creates a rule with a randomly generated rule identifier.
operationId: createRule
description: |
- You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're creating. For example, you must have privileges for the **Management > Stack rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. NOTE: This API supports only token-based authentication. When you create a rule, it identifies which roles you have at that point in time. Thereafter, when the rule performs queries, it uses those security privileges. If a user with different privileges updates the rule, its behavior might change.
+ To create a rule, you must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're creating. For example, you must have privileges for the **Management > Stack rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. This API supports both key- and token-based authentication. To use key-based authentication, create an API key in Kibana and use it in the header of the API call. To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically. In both cases, the API key is subsequently used for authorization when the rule runs.
tags:
- alerting
parameters:
@@ -100,7 +100,7 @@ paths:
summary: Deletes a rule.
operationId: deleteRule
description: |
- You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're deleting. For example, the **Management** > **Stack Rules** feature, **Analytics** > **Discover** or **Machine Learning** features, **Observability**, or **Security** features. WARNING: After you delete a rule, you cannot recover it.
+ To delete a rule, you must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're deleting. For example, the **Management** > **Stack Rules** feature, **Analytics** > **Discover** or **Machine Learning** features, **Observability**, or **Security** features. WARNING: After you delete a rule, you cannot recover it. If the API key that is used by the rule was created automatically, it is deleted.
tags:
- alerting
parameters:
@@ -128,7 +128,7 @@ paths:
summary: Creates a rule with a specific rule identifier.
operationId: createRuleId
description: |
- You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're creating. For example, you must have privileges for the **Management > Stack rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. NOTE: This API supports only token-based authentication. When you create a rule, it identifies which roles you have at that point in time. Thereafter, when the rule performs queries, it uses those security privileges. If a user with different privileges updates the rule, its behavior might change.
+ To create a rule, you must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're creating. For example, you must have privileges for the **Management > Stack rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. This API supports both key- and token-based authentication. To use key-based authentication, create an API key in Kibana and use it in the header of the API call. To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically. In both cases, the API key is subsequently used for authorization when the rule runs.
tags:
- alerting
parameters:
@@ -179,7 +179,7 @@ paths:
summary: Updates the attributes for a rule.
operationId: updateRule
description: |
- You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're updating. For example, you must have privileges for the **Management > Stack rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. NOTE: This API supports only token-based authentication. When you update a rule, it identifies which roles you have at that point in time. Thereafter, when the rule performs queries, it uses those security privileges. If you have different privileges than the user that created or most recently updated the rule, you might change its behavior. Though some properties are optional, when you update the rule the existing property values are overwritten with default values. Therefore, it is recommended to explicitly set all property values.
+ To update a rule, you must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're updating. For example, you must have privileges for the **Management > Stack rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. This API supports both key- and token-based authentication. To use key-based authentication, create an API key in Kibana and use it in the header of the API call. To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically. In both cases, the API key is subsequently used for authorization when the rule runs. NOTE: If the API key has different privileges than the key that created or most recently updated the rule, the rule behavior might change. Though some properties are optional, when you update the rule the existing property values are overwritten with default values. Therefore, it is recommended to explicitly set all property values.
tags:
- alerting
parameters:
@@ -257,7 +257,7 @@ paths:
summary: Enables a rule.
operationId: enableRule
description: |
- This API supports token-based authentication only. You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features.
+ To enable a rule, you must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features. This API supports both key- and token-based authentication. To use key-based authentication, create an API key in Kibana and use it in the header of the API call. To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically. In both cases, the API key is subsequently used for authorization when the rule runs.
tags:
- alerting
parameters:
diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule.yaml
index 943efd9c0d470..1db9d39b096e6 100644
--- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule.yaml
+++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule.yaml
@@ -2,13 +2,13 @@ post:
summary: Creates a rule with a randomly generated rule identifier.
operationId: createRule
description: >
- You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're creating.
+ To create a rule, you must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're creating.
For example, you must have privileges for the **Management > Stack rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features.
If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature.
- NOTE: This API supports only token-based authentication.
- When you create a rule, it identifies which roles you have at that point in time.
- Thereafter, when the rule performs queries, it uses those security privileges.
- If a user with different privileges updates the rule, its behavior might change.
+ This API supports both key- and token-based authentication.
+ To use key-based authentication, create an API key in Kibana and use it in the header of the API call.
+ To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically.
+ In both cases, the API key is subsequently used for authorization when the rule runs.
tags:
- alerting
parameters:
diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}.yaml
index 7ede8da710ea0..66d05da081457 100644
--- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}.yaml
+++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}.yaml
@@ -42,11 +42,10 @@ delete:
summary: Deletes a rule.
operationId: deleteRule
description: >
- You must have `all` privileges for the appropriate Kibana features, depending
- on the `consumer` and `rule_type_id` of the rule you're deleting. For example,
- the **Management** > **Stack Rules** feature, **Analytics** > **Discover** or
- **Machine Learning** features, **Observability**, or **Security** features.
+ To delete a rule, you must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're deleting.
+ For example, the **Management** > **Stack Rules** feature, **Analytics** > **Discover** or **Machine Learning** features, **Observability**, or **Security** features.
WARNING: After you delete a rule, you cannot recover it.
+ If the API key that is used by the rule was created automatically, it is deleted.
tags:
- alerting
parameters:
@@ -75,17 +74,13 @@ post:
summary: Creates a rule with a specific rule identifier.
operationId: createRuleId
description: >
- You must have `all` privileges for the appropriate Kibana features,
- depending on the `consumer` and `rule_type_id` of the rule you're creating.
- For example, you must have privileges for the **Management > Stack rules**
- feature, **Analytics > Discover** and **Machine Learning** features,
- **Observability** features, or **Security** features. If the rule has
- actions, you must also have `read` privileges for the
- **Management > Actions and Connectors** feature. NOTE: This API supports
- only token-based authentication. When you create a rule, it identifies which
- roles you have at that point in time. Thereafter, when the rule performs
- queries, it uses those security privileges. If a user with different
- privileges updates the rule, its behavior might change.
+ To create a rule, you must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're creating.
+ For example, you must have privileges for the **Management > Stack rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features.
+ If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature.
+ This API supports both key- and token-based authentication.
+ To use key-based authentication, create an API key in Kibana and use it in the header of the API call.
+ To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically.
+ In both cases, the API key is subsequently used for authorization when the rule runs.
tags:
- alerting
parameters:
@@ -138,19 +133,15 @@ put:
summary: Updates the attributes for a rule.
operationId: updateRule
description: >
- You must have `all` privileges for the appropriate Kibana features,
- depending on the `consumer` and `rule_type_id` of the rule you're updating.
- For example, you must have privileges for the **Management > Stack rules**
- feature, **Analytics > Discover** and **Machine Learning** features,
- **Observability** features, or **Security** features. If the rule has
- actions, you must also have `read` privileges for the
- **Management > Actions and Connectors** feature. NOTE: This API supports
- only token-based authentication. When you update a rule, it identifies which
- roles you have at that point in time. Thereafter, when the rule performs
- queries, it uses those security privileges. If you have different privileges
- than the user that created or most recently updated the rule, you might
- change its behavior. Though some properties are optional, when you update
- the rule the existing property values are overwritten with default values.
+ To update a rule, you must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule you're updating.
+ For example, you must have privileges for the **Management > Stack rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features.
+ If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature.
+ This API supports both key- and token-based authentication.
+ To use key-based authentication, create an API key in Kibana and use it in the header of the API call.
+ To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically.
+ In both cases, the API key is subsequently used for authorization when the rule runs.
+ NOTE: If the API key has different privileges than the key that created or most recently updated the rule, the rule behavior might change.
+ Though some properties are optional, when you update the rule the existing property values are overwritten with default values.
Therefore, it is recommended to explicitly set all property values.
tags:
- alerting
diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_enable.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_enable.yaml
index cb7991c2d9185..3759acc7093a1 100644
--- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_enable.yaml
+++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_enable.yaml
@@ -2,11 +2,12 @@ post:
summary: Enables a rule.
operationId: enableRule
description: >
- This API supports token-based authentication only.
- You must have `all` privileges for the appropriate Kibana features,
- depending on the `consumer` and `rule_type_id` of the rule. For example, the
- **Management > Stack Rules** feature, **Analytics > Discover** and
- **Machine Learning** features, **Observability**, and **Security** features.
+ To enable a rule, you must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule.
+ For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features.
+ This API supports both key- and token-based authentication.
+ To use key-based authentication, create an API key in Kibana and use it in the header of the API call.
+ To use token-based authentication, provide a username and password; an API key that matches the current privileges of the user is created automatically.
+ In both cases, the API key is subsequently used for authorization when the rule runs.
tags:
- alerting
parameters:
diff --git a/x-pack/plugins/apm/jest.config.js b/x-pack/plugins/apm/jest.config.js
index cc985407698bf..5d15dd048d4f1 100644
--- a/x-pack/plugins/apm/jest.config.js
+++ b/x-pack/plugins/apm/jest.config.js
@@ -11,10 +11,7 @@ module.exports = {
preset: '@kbn/test',
rootDir: path.resolve(__dirname, '../../..'),
roots: ['/x-pack/plugins/apm'],
- setupFiles: [
- '/x-pack/plugins/apm/jest_setup.js',
- '/x-pack/plugins/apm/.storybook/jest_setup.js',
- ],
+ setupFiles: ['/x-pack/plugins/apm/.storybook/jest_setup.js'],
coverageDirectory: '/target/kibana-coverage/jest/x-pack/plugins/apm',
coverageReporters: ['text', 'html'],
collectCoverageFrom: [
diff --git a/x-pack/plugins/apm/jest_setup.js b/x-pack/plugins/apm/jest_setup.js
deleted file mode 100644
index 0c56a092850ab..0000000000000
--- a/x-pack/plugins/apm/jest_setup.js
+++ /dev/null
@@ -1,15 +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
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-/* global jest */
-
-// When a `console.error` is encountered, throw the error to make the test fail.
-// This effectively treats logged errors during the test run as failures.
-jest.spyOn(console, 'error').mockImplementation((message, ...args) => {
- console.log(message, ...args);
- throw new Error(message);
-});
diff --git a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx
index 3457d19ccc908..89f66abaf3f94 100644
--- a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx
+++ b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx
@@ -451,7 +451,8 @@ describe('Case View Page activity tab', () => {
});
describe('Case users', () => {
- describe('Participants', () => {
+ // FLAKY: https://github.com/elastic/kibana/issues/152204
+ describe.skip('Participants', () => {
it('should render the participants correctly', async () => {
appMockRender = createAppMockRenderer();
appMockRender.render();
diff --git a/x-pack/plugins/cloud_defend/common/constants.ts b/x-pack/plugins/cloud_defend/common/constants.ts
index 0bf74aeaaab02..4f528b1e33edd 100755
--- a/x-pack/plugins/cloud_defend/common/constants.ts
+++ b/x-pack/plugins/cloud_defend/common/constants.ts
@@ -10,8 +10,17 @@ export const PLUGIN_ID = 'cloudDefend';
export const PLUGIN_NAME = 'Cloud Defend';
export const INTEGRATION_PACKAGE_NAME = 'cloud_defend';
export const INPUT_CONTROL = 'cloud_defend/control';
+
+export const LOGS_CLOUD_DEFEND_PATTERN = 'logs-cloud_defend.*';
export const ALERTS_DATASET = 'cloud_defend.alerts';
-export const ALERTS_INDEX_PATTERN = 'cloud_defend.alerts*';
+export const ALERTS_INDEX_PATTERN = 'logs-cloud_defend.alerts*';
+export const ALERTS_INDEX_PATTERN_DEFAULT_NS = 'logs-cloud_defend.alerts-default';
+export const FILE_DATASET = 'cloud_defend.file';
+export const FILE_INDEX_PATTERN = 'logs-cloud_defend.file*';
+export const FILE_INDEX_PATTERN_DEFAULT_NS = 'logs-cloud_defend.file-default';
+export const PROCESS_DATASET = 'cloud_defend.process';
+export const PROCESS_INDEX_PATTERN = 'logs-cloud_defend.process*';
+export const PROCESS_INDEX_PATTERN_DEFAULT_NS = 'logs-cloud_defend.process-default';
export const CURRENT_API_VERSION = '1';
export const POLICIES_ROUTE_PATH = '/internal/cloud_defend/policies';
diff --git a/x-pack/plugins/cloud_defend/common/index.ts b/x-pack/plugins/cloud_defend/common/index.ts
index 7ba8cc3ffff7c..25bd5ac7b2751 100644
--- a/x-pack/plugins/cloud_defend/common/index.ts
+++ b/x-pack/plugins/cloud_defend/common/index.ts
@@ -12,6 +12,11 @@ export type {
AgentPolicyStatus,
CloudDefendPolicy,
PoliciesQueryParams,
+ SelectorType,
+ SelectorCondition,
+ ResponseAction,
+ Selector,
+ Response,
} from './latest';
export { policiesQueryParamsSchema } from './latest';
diff --git a/x-pack/plugins/cloud_defend/common/utils/helpers.test.ts b/x-pack/plugins/cloud_defend/common/utils/helpers.test.ts
new file mode 100644
index 0000000000000..a61aa0f70f5d9
--- /dev/null
+++ b/x-pack/plugins/cloud_defend/common/utils/helpers.test.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
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { getSelectorsAndResponsesFromYaml, getYamlFromSelectorsAndResponses } from './helpers';
+import { MOCK_YAML_CONFIGURATION, MOCK_YAML_INVALID_CONFIGURATION } from '../../public/test/mocks';
+
+describe('getSelectorsAndResponsesFromYaml', () => {
+ it('converts yaml into arrays of selectors and responses', () => {
+ const { selectors, responses } = getSelectorsAndResponsesFromYaml(MOCK_YAML_CONFIGURATION);
+
+ expect(selectors).toHaveLength(3);
+ expect(responses).toHaveLength(2);
+ });
+
+ it('returns empty arrays if bad yaml', () => {
+ const { selectors, responses } = getSelectorsAndResponsesFromYaml(
+ MOCK_YAML_INVALID_CONFIGURATION
+ );
+
+ expect(selectors).toHaveLength(0);
+ expect(responses).toHaveLength(0);
+ });
+});
+
+describe('getYamlFromSelectorsAndResponses', () => {
+ it('converts arrays of selectors and responses into yaml', () => {
+ const { selectors, responses } = getSelectorsAndResponsesFromYaml(MOCK_YAML_CONFIGURATION);
+ const yaml = getYamlFromSelectorsAndResponses(selectors, responses);
+ expect(yaml).toEqual(MOCK_YAML_CONFIGURATION);
+ });
+});
diff --git a/x-pack/plugins/cloud_defend/common/utils/helpers.ts b/x-pack/plugins/cloud_defend/common/utils/helpers.ts
index 14b506e8d2e70..ae1b3a4f3d00c 100644
--- a/x-pack/plugins/cloud_defend/common/utils/helpers.ts
+++ b/x-pack/plugins/cloud_defend/common/utils/helpers.ts
@@ -4,9 +4,11 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-
+import yaml from 'js-yaml';
+import { NewPackagePolicy } from '@kbn/fleet-plugin/common';
import { Truthy } from 'lodash';
import { INTEGRATION_PACKAGE_NAME } from '../constants';
+import { Selector, Response } from '..';
/**
* @example
@@ -33,3 +35,77 @@ export function assert(condition: any, msg?: string): asserts condition {
export const isCloudDefendPackage = (packageName?: string) =>
packageName === INTEGRATION_PACKAGE_NAME;
+
+export function getInputFromPolicy(policy: NewPackagePolicy, inputId: string) {
+ return policy.inputs.find((input) => input.type === inputId);
+}
+
+export function getSelectorsAndResponsesFromYaml(configuration: string): {
+ selectors: Selector[];
+ responses: Response[];
+} {
+ let selectors: Selector[] = [];
+ let responses: Response[] = [];
+
+ try {
+ const result = yaml.load(configuration);
+
+ if (result) {
+ // iterate selector/response types
+ Object.keys(result).forEach((selectorType) => {
+ const obj = result[selectorType];
+
+ if (obj.selectors) {
+ selectors = selectors.concat(
+ obj.selectors.map((selector: any) => ({ ...selector, type: selectorType }))
+ );
+ }
+
+ if (obj.responses) {
+ responses = responses.concat(
+ obj.responses.map((response: any) => ({ ...response, type: selectorType }))
+ );
+ }
+ });
+ }
+ } catch {
+ // noop
+ }
+ return { selectors, responses };
+}
+
+export function getYamlFromSelectorsAndResponses(selectors: Selector[], responses: Response[]) {
+ const schema: any = {};
+
+ selectors.reduce((current, selector: any) => {
+ if (current && selector) {
+ if (current[selector.type]) {
+ current[selector.type]?.selectors.push(selector);
+ } else {
+ current[selector.type] = { selectors: [selector], responses: [] };
+ }
+ }
+
+ // the 'any' cast is used so we can keep 'selector.type' type safe
+ delete selector.type;
+
+ return current;
+ }, schema);
+
+ responses.reduce((current, response: any) => {
+ if (current && response) {
+ if (current[response.type]) {
+ current[response.type].responses.push(response);
+ } else {
+ current[response.type] = { selectors: [], responses: [response] };
+ }
+ }
+
+ // the 'any' cast is used so we can keep 'response.type' type safe
+ delete response.type;
+
+ return current;
+ }, schema);
+
+ return yaml.dump(schema);
+}
diff --git a/x-pack/plugins/cloud_defend/common/v1.ts b/x-pack/plugins/cloud_defend/common/v1.ts
index c3bdbb4418183..03365b9092199 100644
--- a/x-pack/plugins/cloud_defend/common/v1.ts
+++ b/x-pack/plugins/cloud_defend/common/v1.ts
@@ -52,3 +52,68 @@ export interface CloudDefendPolicy {
package_policy: PackagePolicy;
agent_policy: AgentPolicyStatus;
}
+
+/**
+ * cloud_defend/control types
+ */
+
+// Currently we support file and process selectors (which match on their respective set of hook points)
+export type SelectorType = 'file' | 'process';
+
+export type SelectorCondition =
+ | 'containerImageFullName'
+ | 'containerImageName'
+ | 'containerImageTag'
+ | 'kubernetesClusterId'
+ | 'kubernetesClusterName'
+ | 'kubernetesNamespace'
+ | 'kubernetesPodLabel'
+ | 'kubernetesPodName'
+ | 'targetFilePath'
+ | 'ignoreVolumeFiles'
+ | 'ignoreVolumeMounts'
+ | 'operation'
+ | 'processExecutable'
+ | 'processName'
+ | 'sessionLeaderInteractive';
+
+export type ResponseAction = 'log' | 'alert' | 'block';
+
+export interface Selector {
+ name: string;
+ operation?: string[];
+ containerImageFullName?: string[];
+ containerImageName?: string[];
+ containerImageTag?: string[];
+ kubernetesClusterId?: string[];
+ kubernetesClusterName?: string[];
+ kubernetesNamespace?: string[];
+ kubernetesPodLabel?: string[];
+ kubernetesPodName?: string[];
+
+ // selector properties
+ targetFilePath?: string[];
+ ignoreVolumeFiles?: boolean;
+ ignoreVolumeMounts?: boolean;
+
+ // process selector properties
+ processExecutable?: string[];
+ processName?: string[];
+ sessionLeaderInteractive?: boolean;
+
+ // non yaml fields
+ type: SelectorType;
+ // used to track selector error state in UI
+ hasErrors?: boolean;
+}
+
+export interface Response {
+ match: string[];
+ exclude?: string[];
+ actions: ResponseAction[];
+
+ // non yaml fields
+ type: SelectorType;
+ // used to track response error state in UI
+ hasErrors?: boolean;
+}
diff --git a/x-pack/plugins/cloud_defend/public/common/utils.test.ts b/x-pack/plugins/cloud_defend/public/common/utils.test.ts
index ede1dfec5b421..7c1f249c1811c 100644
--- a/x-pack/plugins/cloud_defend/public/common/utils.test.ts
+++ b/x-pack/plugins/cloud_defend/public/common/utils.test.ts
@@ -6,43 +6,14 @@
*/
import {
- getSelectorsAndResponsesFromYaml,
- getYamlFromSelectorsAndResponses,
getSelectorConditions,
conditionCombinationInvalid,
getRestrictedValuesForCondition,
validateBlockRestrictions,
selectorsIncludeConditionsForFIMOperationsUsingSlashStarStar,
} from './utils';
-import { MOCK_YAML_CONFIGURATION, MOCK_YAML_INVALID_CONFIGURATION } from '../test/mocks';
-import { Selector, Response } from '../types';
-
-describe('getSelectorsAndResponsesFromYaml', () => {
- it('converts yaml into arrays of selectors and responses', () => {
- const { selectors, responses } = getSelectorsAndResponsesFromYaml(MOCK_YAML_CONFIGURATION);
-
- expect(selectors).toHaveLength(3);
- expect(responses).toHaveLength(2);
- });
-
- it('returns empty arrays if bad yaml', () => {
- const { selectors, responses } = getSelectorsAndResponsesFromYaml(
- MOCK_YAML_INVALID_CONFIGURATION
- );
-
- expect(selectors).toHaveLength(0);
- expect(responses).toHaveLength(0);
- });
-});
-
-describe('getYamlFromSelectorsAndResponses', () => {
- it('converts arrays of selectors and responses into yaml', () => {
- const { selectors, responses } = getSelectorsAndResponsesFromYaml(MOCK_YAML_CONFIGURATION);
- const yaml = getYamlFromSelectorsAndResponses(selectors, responses);
- expect(yaml).toEqual(MOCK_YAML_CONFIGURATION);
- });
-});
+import { Selector, Response } from '../../common';
describe('getSelectorConditions', () => {
it('grabs file conditions for file selectors', () => {
diff --git a/x-pack/plugins/cloud_defend/public/common/utils.ts b/x-pack/plugins/cloud_defend/public/common/utils.ts
index 8200bb866db8a..2ad4697191525 100644
--- a/x-pack/plugins/cloud_defend/public/common/utils.ts
+++ b/x-pack/plugins/cloud_defend/public/common/utils.ts
@@ -4,32 +4,23 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-import yaml from 'js-yaml';
import { uniq } from 'lodash';
-import { NewPackagePolicy } from '@kbn/fleet-plugin/public';
import { i18n } from '@kbn/i18n';
import { errorBlockActionRequiresTargetFilePath } from '../components/control_general_view/translations';
import {
- Selector,
- Response,
- SelectorType,
DefaultFileSelector,
DefaultProcessSelector,
DefaultFileResponse,
DefaultProcessResponse,
SelectorConditionsMap,
- SelectorCondition,
} from '../types';
+import { Selector, Response, SelectorType, SelectorCondition } from '../../common';
import {
MAX_CONDITION_VALUE_LENGTH_BYTES,
MAX_SELECTORS_AND_RESPONSES_PER_TYPE,
FIM_OPERATIONS,
} from './constants';
-export function getInputFromPolicy(policy: NewPackagePolicy, inputId: string) {
- return policy.inputs.find((input) => input.type === inputId);
-}
-
export function getSelectorTypeIcon(type: SelectorType) {
switch (type) {
case 'process':
@@ -262,73 +253,3 @@ export function getDefaultResponseByType(type: SelectorType): Response {
return { ...DefaultFileResponse };
}
}
-
-export function getSelectorsAndResponsesFromYaml(configuration: string): {
- selectors: Selector[];
- responses: Response[];
-} {
- let selectors: Selector[] = [];
- let responses: Response[] = [];
-
- try {
- const result = yaml.load(configuration);
-
- if (result) {
- // iterate selector/response types
- Object.keys(result).forEach((selectorType) => {
- const obj = result[selectorType];
-
- if (obj.selectors) {
- selectors = selectors.concat(
- obj.selectors.map((selector: any) => ({ ...selector, type: selectorType }))
- );
- }
-
- if (obj.responses) {
- responses = responses.concat(
- obj.responses.map((response: any) => ({ ...response, type: selectorType }))
- );
- }
- });
- }
- } catch {
- // noop
- }
- return { selectors, responses };
-}
-
-export function getYamlFromSelectorsAndResponses(selectors: Selector[], responses: Response[]) {
- const schema: any = {};
-
- selectors.reduce((current, selector: any) => {
- if (current && selector) {
- if (current[selector.type]) {
- current[selector.type]?.selectors.push(selector);
- } else {
- current[selector.type] = { selectors: [selector], responses: [] };
- }
- }
-
- // the 'any' cast is used so we can keep 'selector.type' type safe
- delete selector.type;
-
- return current;
- }, schema);
-
- responses.reduce((current, response: any) => {
- if (current && response) {
- if (current[response.type]) {
- current[response.type].responses.push(response);
- } else {
- current[response.type] = { selectors: [], responses: [response] };
- }
- }
-
- // the 'any' cast is used so we can keep 'response.type' type safe
- delete response.type;
-
- return current;
- }, schema);
-
- return yaml.dump(schema);
-}
diff --git a/x-pack/plugins/cloud_defend/public/components/control_general_view/index.test.tsx b/x-pack/plugins/cloud_defend/public/components/control_general_view/index.test.tsx
index c8ca5d281f954..6b27395e10d4f 100644
--- a/x-pack/plugins/cloud_defend/public/components/control_general_view/index.test.tsx
+++ b/x-pack/plugins/cloud_defend/public/components/control_general_view/index.test.tsx
@@ -16,7 +16,7 @@ import {
MOCK_YAML_TOO_MANY_FILE_SELECTORS_RESPONSES,
} from '../../test/mocks';
import { ControlGeneralView } from '.';
-import { getInputFromPolicy } from '../../common/utils';
+import { getInputFromPolicy } from '../../../common/utils/helpers';
import { INPUT_CONTROL } from '../../../common/constants';
describe('', () => {
diff --git a/x-pack/plugins/cloud_defend/public/components/control_general_view/index.tsx b/x-pack/plugins/cloud_defend/public/components/control_general_view/index.tsx
index 701223da1ecad..9cee97cd68540 100644
--- a/x-pack/plugins/cloud_defend/public/components/control_general_view/index.tsx
+++ b/x-pack/plugins/cloud_defend/public/components/control_general_view/index.tsx
@@ -19,14 +19,17 @@ import {
import { INPUT_CONTROL } from '../../../common/constants';
import { useStyles } from './styles';
import {
- getInputFromPolicy,
- getYamlFromSelectorsAndResponses,
- getSelectorsAndResponsesFromYaml,
getDefaultSelectorByType,
getDefaultResponseByType,
getTotalsByType,
} from '../../common/utils';
-import { SelectorType, Selector, Response, ViewDeps } from '../../types';
+import {
+ getInputFromPolicy,
+ getYamlFromSelectorsAndResponses,
+ getSelectorsAndResponsesFromYaml,
+} from '../../../common/utils/helpers';
+import { ViewDeps } from '../../types';
+import { SelectorType, Selector, Response } from '../../../common';
import * as i18n from './translations';
import { ControlGeneralViewSelector } from '../control_general_view_selector';
import { ControlGeneralViewResponse } from '../control_general_view_response';
diff --git a/x-pack/plugins/cloud_defend/public/components/control_general_view/translations.ts b/x-pack/plugins/cloud_defend/public/components/control_general_view/translations.ts
index aae5e8d921025..d59cd47c08f7a 100644
--- a/x-pack/plugins/cloud_defend/public/components/control_general_view/translations.ts
+++ b/x-pack/plugins/cloud_defend/public/components/control_general_view/translations.ts
@@ -6,7 +6,7 @@
*/
import { i18n } from '@kbn/i18n';
-import { SelectorCondition, SelectorType } from '../../types';
+import { SelectorCondition, SelectorType } from '../../../common';
export const fileSelector = i18n.translate('xpack.cloudDefend.fileSelector', {
defaultMessage: 'File selector',
diff --git a/x-pack/plugins/cloud_defend/public/components/control_general_view_response/index.test.tsx b/x-pack/plugins/cloud_defend/public/components/control_general_view_response/index.test.tsx
index aabf4e25599b3..5fbdd9f55135c 100644
--- a/x-pack/plugins/cloud_defend/public/components/control_general_view_response/index.test.tsx
+++ b/x-pack/plugins/cloud_defend/public/components/control_general_view_response/index.test.tsx
@@ -10,7 +10,7 @@ import { coreMock } from '@kbn/core/public/mocks';
import userEvent from '@testing-library/user-event';
import { TestProvider } from '../../test/test_provider';
import { ControlGeneralViewResponse } from '.';
-import { Response, Selector } from '../../types';
+import { Response, Selector } from '../../../common';
import * as i18n from '../control_general_view/translations';
describe('', () => {
diff --git a/x-pack/plugins/cloud_defend/public/components/control_general_view_response/index.tsx b/x-pack/plugins/cloud_defend/public/components/control_general_view_response/index.tsx
index 05ab2dca5fc60..c9872f1a0fe83 100644
--- a/x-pack/plugins/cloud_defend/public/components/control_general_view_response/index.tsx
+++ b/x-pack/plugins/cloud_defend/public/components/control_general_view_response/index.tsx
@@ -30,12 +30,8 @@ import {
} from '@elastic/eui';
import { useStyles } from './styles';
import { useStyles as useSelectorStyles } from '../control_general_view_selector/styles';
-import {
- ControlGeneralViewResponseDeps,
- ResponseAction,
- Response,
- ControlFormErrorMap,
-} from '../../types';
+import { ControlGeneralViewResponseDeps, ControlFormErrorMap } from '../../types';
+import { Response, ResponseAction } from '../../../common';
import * as i18n from '../control_general_view/translations';
import {
getSelectorTypeIcon,
@@ -405,20 +401,18 @@ export const ControlGeneralViewResponse = ({
onChange={onToggleAction}
/>
- {response.type === 'file' && (
-
-
-
-
-
- )}
+
+
+
+
+
diff --git a/x-pack/plugins/cloud_defend/public/components/control_general_view_selector/index.test.tsx b/x-pack/plugins/cloud_defend/public/components/control_general_view_selector/index.test.tsx
index c83f802ae49b7..ae7dc61a2f67c 100644
--- a/x-pack/plugins/cloud_defend/public/components/control_general_view_selector/index.test.tsx
+++ b/x-pack/plugins/cloud_defend/public/components/control_general_view_selector/index.test.tsx
@@ -10,7 +10,7 @@ import { coreMock } from '@kbn/core/public/mocks';
import userEvent from '@testing-library/user-event';
import { TestProvider } from '../../test/test_provider';
import { ControlGeneralViewSelector } from '.';
-import { Selector } from '../../types';
+import { Selector } from '../../../common';
import { getSelectorConditions } from '../../common/utils';
import * as i18n from '../control_general_view/translations';
diff --git a/x-pack/plugins/cloud_defend/public/components/control_general_view_selector/index.tsx b/x-pack/plugins/cloud_defend/public/components/control_general_view_selector/index.tsx
index ba14034a92182..04033509fbe7f 100644
--- a/x-pack/plugins/cloud_defend/public/components/control_general_view_selector/index.tsx
+++ b/x-pack/plugins/cloud_defend/public/components/control_general_view_selector/index.tsx
@@ -29,10 +29,9 @@ import { useStyles } from './styles';
import {
ControlGeneralViewSelectorDeps,
ControlFormErrorMap,
- Selector,
- SelectorCondition,
SelectorConditionsMap,
} from '../../types';
+import { Selector, SelectorCondition } from '../../../common';
import {
getSelectorConditions,
camelToSentenceCase,
diff --git a/x-pack/plugins/cloud_defend/public/components/control_yaml_view/hooks/use_config_model.ts b/x-pack/plugins/cloud_defend/public/components/control_yaml_view/hooks/use_config_model.ts
index 862b0cd27bc92..42154a6fe13e7 100644
--- a/x-pack/plugins/cloud_defend/public/components/control_yaml_view/hooks/use_config_model.ts
+++ b/x-pack/plugins/cloud_defend/public/components/control_yaml_view/hooks/use_config_model.ts
@@ -7,7 +7,7 @@
import { useMemo } from 'react';
import { setDiagnosticsOptions } from 'monaco-yaml';
import { monaco } from '@kbn/monaco';
-import { getSelectorsAndResponsesFromYaml } from '../../../common/utils';
+import { getSelectorsAndResponsesFromYaml } from '../../../../common/utils/helpers';
/**
* In order to keep this json in sync with https://github.com/elastic/cloud-defend/blob/main/modules/service/policy-schema.json
diff --git a/x-pack/plugins/cloud_defend/public/components/control_yaml_view/index.tsx b/x-pack/plugins/cloud_defend/public/components/control_yaml_view/index.tsx
index b93a281f232f1..2e9a3a97ae7d5 100644
--- a/x-pack/plugins/cloud_defend/public/components/control_yaml_view/index.tsx
+++ b/x-pack/plugins/cloud_defend/public/components/control_yaml_view/index.tsx
@@ -13,14 +13,17 @@ import { INPUT_CONTROL } from '../../../common/constants';
import { useStyles } from './styles';
import { useConfigModel } from './hooks/use_config_model';
import {
- getInputFromPolicy,
validateStringValuesForCondition,
- getSelectorsAndResponsesFromYaml,
validateMaxSelectorsAndResponses,
validateBlockRestrictions,
} from '../../common/utils';
+import {
+ getInputFromPolicy,
+ getSelectorsAndResponsesFromYaml,
+} from '../../../common/utils/helpers';
import * as i18n from './translations';
-import { ViewDeps, SelectorConditionsMap, SelectorCondition } from '../../types';
+import { ViewDeps, SelectorConditionsMap } from '../../types';
+import { SelectorCondition } from '../../../common';
const { editor } = monaco;
diff --git a/x-pack/plugins/cloud_defend/public/components/policy_settings/index.test.tsx b/x-pack/plugins/cloud_defend/public/components/policy_settings/index.test.tsx
index f4d0a4ddc6b5b..ced9dfe0171fa 100644
--- a/x-pack/plugins/cloud_defend/public/components/policy_settings/index.test.tsx
+++ b/x-pack/plugins/cloud_defend/public/components/policy_settings/index.test.tsx
@@ -10,7 +10,7 @@ import userEvent from '@testing-library/user-event';
import { TestProvider } from '../../test/test_provider';
import { getCloudDefendNewPolicyMock } from '../../test/mocks';
import { PolicySettings } from '.';
-import { getInputFromPolicy } from '../../common/utils';
+import { getInputFromPolicy } from '../../../common/utils/helpers';
import { INPUT_CONTROL } from '../../../common/constants';
describe('', () => {
diff --git a/x-pack/plugins/cloud_defend/public/components/policy_settings/index.tsx b/x-pack/plugins/cloud_defend/public/components/policy_settings/index.tsx
index 6c1e6abdc93cb..0c74551183942 100644
--- a/x-pack/plugins/cloud_defend/public/components/policy_settings/index.tsx
+++ b/x-pack/plugins/cloud_defend/public/components/policy_settings/index.tsx
@@ -18,7 +18,7 @@ import {
EuiHorizontalRule,
} from '@elastic/eui';
import { INPUT_CONTROL } from '../../../common/constants';
-import { getInputFromPolicy } from '../../common/utils';
+import { getInputFromPolicy } from '../../../common/utils/helpers';
import * as i18n from './translations';
import { ControlSettings } from '../control_settings';
import { SettingsDeps, OnChangeDeps } from '../../types';
diff --git a/x-pack/plugins/cloud_defend/public/types.ts b/x-pack/plugins/cloud_defend/public/types.ts
index 5ad19220178c4..971a28f9da163 100755
--- a/x-pack/plugins/cloud_defend/public/types.ts
+++ b/x-pack/plugins/cloud_defend/public/types.ts
@@ -16,6 +16,7 @@ import type {
import type { CloudDefendRouterProps } from './application/router';
import type { CloudDefendPageId } from './common/navigation/types';
import * as i18n from './components/control_general_view/translations';
+import { SelectorType, SelectorCondition, Selector, Response } from '../common';
/**
* cloud_defend plugin types
@@ -53,9 +54,6 @@ export interface CloudDefendSecuritySolutionContext {
* cloud_defend/control types
*/
-// Currently we support file and process selectors (which match on their respective set of lsm hook points)
-export type SelectorType = 'file' | 'process';
-
/*
* 'stringArray' uses a EuiComboBox
* 'flag' is a boolean value which is always 'true'
@@ -63,23 +61,6 @@ export type SelectorType = 'file' | 'process';
*/
export type SelectorConditionType = 'stringArray' | 'flag' | 'boolean';
-export type SelectorCondition =
- | 'containerImageFullName'
- | 'containerImageName'
- | 'containerImageTag'
- | 'kubernetesClusterId'
- | 'kubernetesClusterName'
- | 'kubernetesNamespace'
- | 'kubernetesPodLabel'
- | 'kubernetesPodName'
- | 'targetFilePath'
- | 'ignoreVolumeFiles'
- | 'ignoreVolumeMounts'
- | 'operation'
- | 'processExecutable'
- | 'processName'
- | 'sessionLeaderInteractive';
-
export interface SelectorConditionOptions {
type: SelectorConditionType;
pattern?: string;
@@ -155,47 +136,6 @@ export const SelectorConditionsMap: SelectorConditionsMapProps = {
sessionLeaderInteractive: { selectorType: 'process', type: 'boolean' },
};
-export type ResponseAction = 'log' | 'alert' | 'block';
-
-export interface Selector {
- name: string;
- operation?: string[];
- containerImageFullName?: string[];
- containerImageName?: string[];
- containerImageTag?: string[];
- kubernetesClusterId?: string[];
- kubernetesClusterName?: string[];
- kubernetesNamespace?: string[];
- kubernetesPodLabel?: string[];
- kubernetesPodName?: string[];
-
- // selector properties
- targetFilePath?: string[];
- ignoreVolumeFiles?: boolean;
- ignoreVolumeMounts?: boolean;
-
- // process selector properties
- processExecutable?: string[];
- processName?: string[];
- sessionLeaderInteractive?: string[];
-
- // non yaml fields
- type: SelectorType;
- // used to track selector error state in UI
- hasErrors?: boolean;
-}
-
-export interface Response {
- match: string[];
- exclude?: string[];
- actions: ResponseAction[];
-
- // non yaml fields
- type: SelectorType;
- // used to track response error state in UI
- hasErrors?: boolean;
-}
-
export const DefaultFileSelector: Selector = {
type: 'file',
name: 'Untitled',
diff --git a/x-pack/plugins/cloud_defend/server/lib/check_index_status.ts b/x-pack/plugins/cloud_defend/server/lib/check_index_status.ts
index ab882e35fc70e..a02e3a22f1f23 100644
--- a/x-pack/plugins/cloud_defend/server/lib/check_index_status.ts
+++ b/x-pack/plugins/cloud_defend/server/lib/check_index_status.ts
@@ -26,6 +26,7 @@ export const checkIndexStatus = async (
} catch (e) {
logger.debug(e);
if (e?.meta?.body?.error?.type === 'security_exception') {
+ logger.info(e);
return 'unprivileged';
}
diff --git a/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/accounts_stats_collector.ts b/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/accounts_stats_collector.ts
new file mode 100644
index 0000000000000..af29fad6e5918
--- /dev/null
+++ b/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/accounts_stats_collector.ts
@@ -0,0 +1,218 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
+import type { Logger } from '@kbn/core/server';
+import type {
+ AggregationsMultiBucketBase,
+ SearchRequest,
+} from '@elastic/elasticsearch/lib/api/types';
+import type { CloudDefendAccountsStats } from './types';
+import { LOGS_CLOUD_DEFEND_PATTERN } from '../../../../common/constants';
+
+interface Value {
+ value: number;
+}
+
+interface KubernetesVersion {
+ metrics: { 'orchestrator.version': string };
+}
+
+interface CloudProvider {
+ metrics: { 'cloud.provider': string };
+}
+
+interface AccountsStats {
+ accounts: {
+ buckets: AccountEntity[];
+ };
+}
+interface AccountEntity {
+ key: string; // aggregation bucket key (currently: orchestrator.cluster.id)
+ doc_count: number; // total doc count (process + file + alerts)
+ process_doc_count: AggregationsMultiBucketBase;
+ file_doc_count: AggregationsMultiBucketBase;
+ alert_doc_count: AggregationsMultiBucketBase;
+ cloud_provider: { top: CloudProvider[] };
+ kubernetes_version: { top: KubernetesVersion[] };
+ agents_count: Value;
+ nodes_count: Value;
+ pods_count: Value;
+ resources: {
+ pods_count: Value;
+ };
+}
+
+const getAccountsStatsQuery = (): SearchRequest => ({
+ index: LOGS_CLOUD_DEFEND_PATTERN,
+ query: {
+ match_all: {},
+ },
+ aggs: {
+ accounts: {
+ terms: {
+ field: 'orchestrator.cluster.id',
+ order: {
+ _count: 'desc',
+ },
+ size: 100,
+ },
+ aggs: {
+ nodes_count: {
+ cardinality: {
+ field: 'cloud.instance.name',
+ },
+ },
+ agents_count: {
+ cardinality: {
+ field: 'agent.id',
+ },
+ },
+ kubernetes_version: {
+ top_metrics: {
+ metrics: {
+ field: 'orchestrator.version',
+ },
+ size: 1,
+ sort: {
+ '@timestamp': 'desc',
+ },
+ },
+ },
+ cloud_provider: {
+ top_metrics: {
+ metrics: {
+ field: 'cloud.provider',
+ },
+ size: 1,
+ sort: {
+ '@timestamp': 'desc',
+ },
+ },
+ },
+ file_doc_count: {
+ filter: {
+ bool: {
+ filter: [
+ {
+ bool: {
+ should: [
+ {
+ term: {
+ 'event.category': 'file',
+ },
+ },
+ ],
+ minimum_should_match: 1,
+ },
+ },
+ ],
+ },
+ },
+ },
+ process_doc_count: {
+ filter: {
+ bool: {
+ filter: [
+ {
+ bool: {
+ should: [
+ {
+ term: {
+ 'event.category': 'process',
+ },
+ },
+ ],
+ minimum_should_match: 1,
+ },
+ },
+ ],
+ },
+ },
+ },
+ alert_doc_count: {
+ filter: {
+ bool: {
+ filter: [
+ {
+ bool: {
+ should: [
+ {
+ term: {
+ 'event.kind': 'alert',
+ },
+ },
+ ],
+ minimum_should_match: 1,
+ },
+ },
+ ],
+ },
+ },
+ },
+ pods_count: {
+ cardinality: {
+ field: 'orchestrator.resource.name',
+ },
+ },
+ },
+ },
+ },
+
+ size: 0,
+ _source: false,
+});
+
+const getCloudDefendAccountsStats = (
+ aggregatedResourcesStats: AccountsStats,
+ logger: Logger
+): CloudDefendAccountsStats[] => {
+ const accounts = aggregatedResourcesStats.accounts.buckets;
+
+ const cloudDefendAccountsStats = accounts.map((account) => ({
+ account_id: account.key,
+ total_doc_count: account.doc_count,
+ file_doc_count: account.file_doc_count.doc_count,
+ process_doc_count: account.process_doc_count.doc_count,
+ alert_doc_count: account.alert_doc_count.doc_count,
+ kubernetes_version: account.kubernetes_version?.top?.[0]?.metrics['orchestrator.version'],
+ cloud_provider: account.cloud_provider?.top?.[0]?.metrics['cloud.provider'],
+ agents_count: account.agents_count.value,
+ nodes_count: account.nodes_count.value,
+ pods_count: account.pods_count.value,
+ }));
+ logger.info('CloudDefend telemetry: accounts stats was sent');
+
+ return cloudDefendAccountsStats;
+};
+
+export const getAccountsStats = async (
+ esClient: ElasticsearchClient,
+ logger: Logger
+): Promise => {
+ try {
+ const isIndexExists = await esClient.indices.exists({
+ index: LOGS_CLOUD_DEFEND_PATTERN,
+ });
+
+ if (isIndexExists) {
+ const accountsStatsResponse = await esClient.search(
+ getAccountsStatsQuery()
+ );
+
+ const cloudDefendAccountsStats = accountsStatsResponse.aggregations
+ ? getCloudDefendAccountsStats(accountsStatsResponse.aggregations, logger)
+ : [];
+
+ return cloudDefendAccountsStats;
+ }
+
+ return [];
+ } catch (e) {
+ logger.error(`Failed to get account stats ${e}`);
+ return [];
+ }
+};
diff --git a/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/indices_stats_collector.ts b/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/indices_stats_collector.ts
new file mode 100644
index 0000000000000..2c1279952391d
--- /dev/null
+++ b/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/indices_stats_collector.ts
@@ -0,0 +1,107 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import type { CoreStart, Logger, SavedObjectsClientContract } from '@kbn/core/server';
+import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
+import { getCloudDefendStatus } from '../../../routes/status/status';
+import type { CloudDefendPluginStart, CloudDefendPluginStartDeps } from '../../../types';
+
+import type { CloudDefendIndicesStats, IndexStats } from './types';
+import {
+ ALERTS_INDEX_PATTERN,
+ FILE_INDEX_PATTERN,
+ PROCESS_INDEX_PATTERN,
+} from '../../../../common/constants';
+
+const getIndexDocCount = (esClient: ElasticsearchClient, index: string) =>
+ esClient.indices.stats({ index });
+
+const getLatestDocTimestamp = async (
+ esClient: ElasticsearchClient,
+ index: string
+): Promise => {
+ const latestTimestamp = await esClient.search({
+ index,
+ query: {
+ match_all: {},
+ },
+ sort: '@timestamp:desc',
+ size: 1,
+ fields: ['@timestamp'],
+ _source: false,
+ });
+
+ const latestEventTimestamp = latestTimestamp.hits?.hits[0]?.fields;
+
+ return latestEventTimestamp ? latestEventTimestamp['@timestamp'][0] : null;
+};
+
+const getIndexStats = async (
+ esClient: ElasticsearchClient,
+ index: string,
+ logger: Logger
+): Promise => {
+ try {
+ const lastDocTimestamp = await getLatestDocTimestamp(esClient, index);
+
+ if (lastDocTimestamp) {
+ const indexStats = await getIndexDocCount(esClient, index);
+ return {
+ doc_count: indexStats._all.primaries?.docs ? indexStats._all.primaries?.docs?.count : 0,
+ deleted: indexStats._all.primaries?.docs?.deleted
+ ? indexStats._all.primaries?.docs?.deleted
+ : 0,
+ size_in_bytes: indexStats._all.primaries?.store
+ ? indexStats._all.primaries?.store.size_in_bytes
+ : 0,
+ last_doc_timestamp: lastDocTimestamp,
+ };
+ }
+
+ return {};
+ } catch (e) {
+ logger.error(`Failed to get index stats for ${index}`);
+ return {};
+ }
+};
+
+export const getIndicesStats = async (
+ esClient: ElasticsearchClient,
+ soClient: SavedObjectsClientContract,
+ coreServices: Promise<[CoreStart, CloudDefendPluginStartDeps, CloudDefendPluginStart]>,
+ logger: Logger
+): Promise => {
+ const [alerts, file, process] = await Promise.all([
+ getIndexStats(esClient, ALERTS_INDEX_PATTERN, logger),
+ getIndexStats(esClient, FILE_INDEX_PATTERN, logger),
+ getIndexStats(esClient, PROCESS_INDEX_PATTERN, logger),
+ ]);
+
+ const [, cloudDefendPluginStartDeps] = await coreServices;
+
+ const { status, latestPackageVersion, installedPackagePolicies, healthyAgents } =
+ await getCloudDefendStatus({
+ logger,
+ esClient,
+ soClient,
+ agentPolicyService: cloudDefendPluginStartDeps.fleet.agentPolicyService,
+ agentService: cloudDefendPluginStartDeps.fleet.agentService,
+ packagePolicyService: cloudDefendPluginStartDeps.fleet.packagePolicyService,
+ packageService: cloudDefendPluginStartDeps.fleet.packageService,
+ });
+
+ return {
+ alerts,
+ file,
+ process,
+ latestPackageVersion,
+ packageStatus: {
+ status,
+ installedPackagePolicies,
+ healthyAgents,
+ },
+ };
+};
diff --git a/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/installation_stats_collector.ts b/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/installation_stats_collector.ts
new file mode 100644
index 0000000000000..bf159a0f4c5ec
--- /dev/null
+++ b/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/installation_stats_collector.ts
@@ -0,0 +1,89 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import type { CoreStart, Logger, SavedObjectsClientContract } from '@kbn/core/server';
+import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
+import {
+ AgentPolicy,
+ PackagePolicy,
+ PACKAGE_POLICY_SAVED_OBJECT_TYPE,
+ SO_SEARCH_LIMIT,
+} from '@kbn/fleet-plugin/common';
+import { agentPolicyService } from '@kbn/fleet-plugin/server/services';
+import type { CloudDefendInstallationStats } from './types';
+import type { CloudDefendPluginStart, CloudDefendPluginStartDeps } from '../../../types';
+import { INTEGRATION_PACKAGE_NAME, INPUT_CONTROL } from '../../../../common/constants';
+import {
+ getInputFromPolicy,
+ getSelectorsAndResponsesFromYaml,
+} from '../../../../common/utils/helpers';
+
+export const getInstallationStats = async (
+ esClient: ElasticsearchClient,
+ soClient: SavedObjectsClientContract,
+ coreServices: Promise<[CoreStart, CloudDefendPluginStartDeps, CloudDefendPluginStart]>,
+ logger: Logger
+): Promise => {
+ const [, cloudDefendServerPluginStartDeps] = await coreServices;
+
+ const cloudDefendContext = {
+ logger,
+ esClient,
+ soClient,
+ agentPolicyService: cloudDefendServerPluginStartDeps.fleet.agentPolicyService,
+ packagePolicyService: cloudDefendServerPluginStartDeps.fleet.packagePolicyService,
+ };
+
+ const getInstalledPackagePolicies = async (
+ packagePolicies: PackagePolicy[],
+ agentPolicies: AgentPolicy[]
+ ) => {
+ const installationStats = packagePolicies.map(
+ (packagePolicy: PackagePolicy): CloudDefendInstallationStats => {
+ const agentCounts =
+ agentPolicies?.find((agentPolicy) => agentPolicy?.id === packagePolicy.policy_id)
+ ?.agents ?? 0;
+
+ const input = getInputFromPolicy(packagePolicy, INPUT_CONTROL);
+ const policyYaml = input?.vars?.configuration?.value;
+ const { selectors, responses } = getSelectorsAndResponsesFromYaml(policyYaml);
+
+ return {
+ package_policy_id: packagePolicy.id,
+ package_version: packagePolicy.package?.version as string,
+ created_at: packagePolicy.created_at,
+ agent_policy_id: packagePolicy.policy_id,
+ agent_count: agentCounts,
+ policy_yaml: policyYaml,
+ selectors,
+ responses,
+ };
+ }
+ );
+ return installationStats;
+ };
+
+ const packagePolicies = await cloudDefendContext.packagePolicyService.list(soClient, {
+ perPage: SO_SEARCH_LIMIT,
+ kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:"${INTEGRATION_PACKAGE_NAME}"`,
+ });
+
+ const agentPolicies = await agentPolicyService.list(soClient, {
+ perPage: SO_SEARCH_LIMIT,
+ kuery: '',
+ esClient,
+ withAgentCount: true,
+ });
+
+ if (!packagePolicies) return [];
+
+ const installationStats: CloudDefendInstallationStats[] = await getInstalledPackagePolicies(
+ packagePolicies.items,
+ agentPolicies?.items || []
+ );
+
+ return installationStats;
+};
diff --git a/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/pods_stats_collector.ts b/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/pods_stats_collector.ts
new file mode 100644
index 0000000000000..311411ca92cad
--- /dev/null
+++ b/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/pods_stats_collector.ts
@@ -0,0 +1,210 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
+import type { Logger } from '@kbn/core/server';
+import type { SearchRequest } from '@elastic/elasticsearch/lib/api/types';
+import type { CloudDefendPodsStats } from './types';
+import { LOGS_CLOUD_DEFEND_PATTERN } from '../../../../common/constants';
+
+interface PodsStats {
+ accounts: {
+ buckets: AccountEntity[];
+ };
+}
+
+interface Bucket {
+ key: string;
+}
+
+export interface AccountEntity {
+ key: string; // orchestrator.cluster.id
+ doc_count: number;
+ pods: {
+ buckets: Pod[];
+ };
+}
+
+interface Pod {
+ key: string; // orchestrator.resource.name
+ container_image_name: {
+ buckets: Bucket[];
+ };
+ container_image_tag: {
+ buckets: Bucket[];
+ };
+ doc_count: number;
+ file_doc_count: {
+ doc_count: number;
+ };
+ process_doc_count: {
+ doc_count: number;
+ };
+ alert_doc_count: {
+ doc_count: number;
+ };
+}
+
+const getPodsStatsQuery = (index: string): SearchRequest => ({
+ index,
+ query: {
+ match_all: {},
+ },
+ aggs: {
+ accounts: {
+ terms: {
+ field: 'orchestrator.cluster.id',
+ order: {
+ _count: 'desc',
+ },
+ size: 100,
+ },
+ aggs: {
+ // all cloud-defend logs are from the viewpoint of an orchestrator.resource.type = "pod"
+ // so no need to filter by orchestrator.resource.type.
+ pods: {
+ terms: {
+ field: 'orchestrator.resource.name',
+ order: {
+ _count: 'desc',
+ },
+ size: 100,
+ },
+ aggs: {
+ container_image_name: {
+ terms: {
+ field: 'container.image.name',
+ size: 1,
+ },
+ },
+ container_image_tag: {
+ terms: {
+ field: 'container.image.tag',
+ size: 1,
+ },
+ },
+ file_doc_count: {
+ filter: {
+ bool: {
+ filter: [
+ {
+ bool: {
+ should: [
+ {
+ term: {
+ 'event.category': 'file',
+ },
+ },
+ ],
+ minimum_should_match: 1,
+ },
+ },
+ ],
+ },
+ },
+ },
+ process_doc_count: {
+ filter: {
+ bool: {
+ filter: [
+ {
+ bool: {
+ should: [
+ {
+ term: {
+ 'event.category': 'process',
+ },
+ },
+ ],
+ minimum_should_match: 1,
+ },
+ },
+ ],
+ },
+ },
+ },
+ alert_doc_count: {
+ filter: {
+ bool: {
+ filter: [
+ {
+ bool: {
+ should: [
+ {
+ term: {
+ 'event.kind': 'alert',
+ },
+ },
+ ],
+ minimum_should_match: 1,
+ },
+ },
+ ],
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+
+ size: 0,
+ _source: false,
+});
+
+const getCloudDefendPodsStats = (
+ aggregatedPodsStats: PodsStats,
+ logger: Logger
+): CloudDefendPodsStats[] => {
+ const accounts = aggregatedPodsStats.accounts.buckets;
+ const podsStats = accounts.map((account) => {
+ const accountId = account.key;
+ return account.pods.buckets.map((pod) => {
+ return {
+ account_id: accountId,
+ pod_name: pod.key,
+ container_image_name: pod.container_image_name?.buckets?.[0]?.key,
+ container_image_tag: pod.container_image_tag?.buckets?.[0]?.key,
+ total_doc_count: pod.doc_count,
+ file_doc_count: pod.file_doc_count.doc_count,
+ process_doc_count: pod.process_doc_count.doc_count,
+ alert_doc_count: pod.alert_doc_count.doc_count,
+ };
+ });
+ });
+ logger.info('Cloud defend telemetry: pods stats was sent');
+
+ return podsStats.flat(2);
+};
+
+export const getPodsStats = async (
+ esClient: ElasticsearchClient,
+ logger: Logger
+): Promise => {
+ try {
+ const isIndexExists = await esClient.indices.exists({
+ index: LOGS_CLOUD_DEFEND_PATTERN,
+ });
+
+ if (isIndexExists) {
+ const podsStatsResponse = await esClient.search(
+ getPodsStatsQuery(LOGS_CLOUD_DEFEND_PATTERN)
+ );
+
+ const cloudDefendPodsStats = podsStatsResponse.aggregations
+ ? getCloudDefendPodsStats(podsStatsResponse.aggregations, logger)
+ : [];
+
+ return cloudDefendPodsStats;
+ }
+
+ return [];
+ } catch (e) {
+ logger.error(`Failed to get pods stats ${e}`);
+ return [];
+ }
+};
diff --git a/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/register.ts b/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/register.ts
new file mode 100644
index 0000000000000..6b7d53e57f89e
--- /dev/null
+++ b/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/register.ts
@@ -0,0 +1,72 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { CollectorFetchContext, UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
+import type { CoreStart, Logger } from '@kbn/core/server';
+import { CloudDefendPluginStart, CloudDefendPluginStartDeps } from '../../../types';
+import { getIndicesStats } from './indices_stats_collector';
+import { getPodsStats } from './pods_stats_collector';
+import { cloudDefendUsageSchema } from './schema';
+import { CloudDefendUsage } from './types';
+import { getAccountsStats } from './accounts_stats_collector';
+import { getInstallationStats } from './installation_stats_collector';
+
+export function registerCloudDefendUsageCollector(
+ logger: Logger,
+ coreServices: Promise<[CoreStart, CloudDefendPluginStartDeps, CloudDefendPluginStart]>,
+ usageCollection?: UsageCollectionSetup
+): void {
+ // usageCollection is an optional dependency, so make sure to return if it is not registered
+ if (!usageCollection) {
+ logger.debug('Usage collection disabled');
+ return;
+ }
+
+ // Create usage collector
+ const cloudDefendUsageCollector = usageCollection.makeUsageCollector({
+ type: 'cloud_defend',
+ isReady: async () => {
+ await coreServices;
+ return true;
+ },
+ fetch: async (collectorFetchContext: CollectorFetchContext) => {
+ logger.debug('Starting cloud_defend usage collection');
+
+ const [indicesStats, accountsStats, podsStats, installationStats] = await Promise.all([
+ getIndicesStats(
+ collectorFetchContext.esClient,
+ collectorFetchContext.soClient,
+ coreServices,
+ logger
+ ),
+ getAccountsStats(collectorFetchContext.esClient, logger),
+ getPodsStats(collectorFetchContext.esClient, logger),
+ getInstallationStats(
+ collectorFetchContext.esClient,
+ collectorFetchContext.soClient,
+ coreServices,
+ logger
+ ),
+ ]).catch((err) => {
+ logger.error(err);
+
+ return err;
+ });
+
+ return {
+ indices: indicesStats,
+ accounts_stats: accountsStats,
+ pods_stats: podsStats,
+ installation_stats: installationStats,
+ };
+ },
+ schema: cloudDefendUsageSchema,
+ });
+
+ // Register usage collector
+ usageCollection.registerCollector(cloudDefendUsageCollector);
+}
diff --git a/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/schema.ts b/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/schema.ts
new file mode 100644
index 0000000000000..55c6677128c09
--- /dev/null
+++ b/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/schema.ts
@@ -0,0 +1,132 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { MakeSchemaFrom } from '@kbn/usage-collection-plugin/server';
+import type { CloudDefendUsage } from './types';
+
+export const cloudDefendUsageSchema: MakeSchemaFrom = {
+ indices: {
+ alerts: {
+ doc_count: {
+ type: 'long',
+ },
+ deleted: {
+ type: 'long',
+ },
+ size_in_bytes: {
+ type: 'long',
+ },
+ last_doc_timestamp: {
+ type: 'date',
+ },
+ },
+ file: {
+ doc_count: {
+ type: 'long',
+ },
+ deleted: {
+ type: 'long',
+ },
+ size_in_bytes: {
+ type: 'long',
+ },
+ last_doc_timestamp: {
+ type: 'date',
+ },
+ },
+ process: {
+ doc_count: {
+ type: 'long',
+ },
+ deleted: {
+ type: 'long',
+ },
+ size_in_bytes: {
+ type: 'long',
+ },
+ last_doc_timestamp: {
+ type: 'date',
+ },
+ },
+ latestPackageVersion: { type: 'keyword' },
+ packageStatus: {
+ status: { type: 'keyword' },
+ installedPackagePolicies: { type: 'long' },
+ healthyAgents: { type: 'long' },
+ },
+ },
+ pods_stats: {
+ type: 'array',
+ items: {
+ account_id: { type: 'keyword' },
+ container_image_name: { type: 'keyword' },
+ container_image_tag: { type: 'keyword' },
+ pod_name: { type: 'keyword' },
+ total_doc_count: { type: 'long' },
+ process_doc_count: { type: 'long' },
+ file_doc_count: { type: 'long' },
+ alert_doc_count: { type: 'long' },
+ },
+ },
+ accounts_stats: {
+ type: 'array',
+ items: {
+ account_id: { type: 'keyword' },
+ cloud_provider: { type: 'keyword' },
+ kubernetes_version: { type: 'keyword' },
+ total_doc_count: { type: 'long' },
+ file_doc_count: { type: 'long' },
+ process_doc_count: { type: 'long' },
+ alert_doc_count: { type: 'long' },
+ agents_count: { type: 'short' },
+ nodes_count: { type: 'short' },
+ pods_count: { type: 'short' },
+ },
+ },
+ installation_stats: {
+ type: 'array',
+ items: {
+ package_policy_id: { type: 'keyword' },
+ package_version: { type: 'keyword' },
+ agent_policy_id: { type: 'keyword' },
+ created_at: { type: 'date' },
+ agent_count: { type: 'long' },
+ policy_yaml: { type: 'keyword' },
+ selectors: {
+ type: 'array',
+ items: {
+ type: { type: 'keyword' },
+ name: { type: 'keyword' },
+ operation: { type: 'array', items: { type: 'keyword' } },
+ containerImageFullName: { type: 'array', items: { type: 'keyword' } },
+ containerImageName: { type: 'array', items: { type: 'keyword' } },
+ containerImageTag: { type: 'array', items: { type: 'keyword' } },
+ kubernetesClusterId: { type: 'array', items: { type: 'keyword' } },
+ kubernetesClusterName: { type: 'array', items: { type: 'keyword' } },
+ kubernetesNamespace: { type: 'array', items: { type: 'keyword' } },
+ kubernetesPodLabel: { type: 'array', items: { type: 'keyword' } },
+ kubernetesPodName: { type: 'array', items: { type: 'keyword' } },
+ targetFilePath: { type: 'array', items: { type: 'keyword' } },
+ ignoreVolumeFiles: { type: 'boolean' },
+ ignoreVolumeMounts: { type: 'boolean' },
+ processExecutable: { type: 'array', items: { type: 'keyword' } },
+ processName: { type: 'array', items: { type: 'keyword' } },
+ sessionLeaderInteractive: { type: 'boolean' },
+ },
+ },
+ responses: {
+ type: 'array',
+ items: {
+ type: { type: 'keyword' },
+ match: { type: 'array', items: { type: 'keyword' } },
+ exclude: { type: 'array', items: { type: 'keyword' } },
+ actions: { type: 'array', items: { type: 'keyword' } },
+ },
+ },
+ },
+ },
+};
diff --git a/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/types.ts b/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/types.ts
new file mode 100644
index 0000000000000..32de2548cf7c2
--- /dev/null
+++ b/x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/types.ts
@@ -0,0 +1,121 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+// for some reason we can't reference common/index.ts because
+// the `node scripts/check_telemetry.js --fix` command fails with the error
+// ERROR Error: Error extracting collector in x-pack/plugins/cloud_defend/server/lib/telemetry/collectors/register.ts
+// Error: Unable to find identifier in source Selector
+// at createFailError (dev_cli_errors.ts:27:24)
+// at parseUsageCollection (ts_parser.ts:226:32)
+// at parseUsageCollection.next ()
+// at extractCollectors (extract_collectors.ts:58:32)
+// at extractCollectors.next ()
+// at Task.task (extract_collectors_task.ts:43:53)
+// at runMicrotasks ()
+// at processTicksAndRejections (node:internal/process/task_queues:96:5)
+//
+// I guess the intermediate import/export is causing problems
+// for now we will just point to the current version (v1)
+import type {
+ Selector,
+ Response,
+ SelectorType,
+ SelectorCondition,
+ ResponseAction,
+} from '../../../../common/v1';
+
+export interface CloudDefendUsage {
+ indices: CloudDefendIndicesStats;
+ pods_stats: CloudDefendPodsStats[];
+ accounts_stats: CloudDefendAccountsStats[];
+ installation_stats: CloudDefendInstallationStats[];
+}
+
+export interface PackageSetupStatus {
+ status: string;
+ installedPackagePolicies: number;
+ healthyAgents: number;
+}
+
+export interface CloudDefendIndicesStats {
+ alerts: IndexStats | {};
+ file: IndexStats | {};
+ process: IndexStats | {};
+ latestPackageVersion: string;
+ packageStatus: PackageSetupStatus;
+}
+
+export interface IndexStats {
+ doc_count: number;
+ deleted: number;
+ size_in_bytes: number;
+ last_doc_timestamp: string | null;
+}
+
+export interface CloudDefendPodsStats {
+ account_id: string;
+ pod_name: string;
+ container_image_name: string;
+ container_image_tag: string;
+ total_doc_count: number;
+ file_doc_count: number;
+ process_doc_count: number;
+ alert_doc_count: number;
+}
+
+export interface CloudDefendAccountsStats {
+ account_id: string;
+ total_doc_count: number;
+ cloud_provider: string;
+ kubernetes_version: string | null;
+ file_doc_count: number;
+ process_doc_count: number;
+ alert_doc_count: number;
+ agents_count: number;
+ nodes_count: number;
+ pods_count: number;
+}
+
+export type CloudDefendSelectorTypeCounts = {
+ [key in SelectorType]: number;
+};
+
+export type CloudDefendResponseTypeCounts = {
+ [key in SelectorType]: number;
+};
+
+export type CloudDefendConditionsCounts = {
+ [key in SelectorCondition]?: number;
+};
+
+export type CloudDefendActionCounts = {
+ [key in ResponseAction]?: number;
+};
+
+export interface CloudDefendPolicyYamlStats {
+ policy_yaml: string;
+ policy_json: string; // to be used for further digging in BigQuery
+ selector_counts: CloudDefendSelectorTypeCounts;
+ response_counts: CloudDefendResponseTypeCounts;
+ selector_conditions_counts: CloudDefendConditionsCounts;
+ response_actions_counts: CloudDefendActionCounts;
+ response_match_names: string[];
+ response_exclude_names: string[];
+}
+
+type CloudDefendSelector = Omit;
+type CloudDefendResponse = Omit;
+
+export interface CloudDefendInstallationStats {
+ package_policy_id: string;
+ package_version: string;
+ agent_policy_id: string;
+ created_at: string;
+ agent_count: number;
+ policy_yaml: string;
+ selectors: CloudDefendSelector[];
+ responses: CloudDefendResponse[];
+}
diff --git a/x-pack/plugins/cloud_defend/server/plugin.ts b/x-pack/plugins/cloud_defend/server/plugin.ts
index d5254b7782647..c8a6bc5083b1c 100644
--- a/x-pack/plugins/cloud_defend/server/plugin.ts
+++ b/x-pack/plugins/cloud_defend/server/plugin.ts
@@ -23,6 +23,7 @@ import { setupRoutes } from './routes/setup_routes';
import { isCloudDefendPackage } from '../common/utils/helpers';
import { isSubscriptionAllowed } from '../common/utils/subscription';
import { onPackagePolicyPostCreateCallback } from './lib/fleet_util';
+import { registerCloudDefendUsageCollector } from './lib/telemetry/collectors/register';
export class CloudDefendPlugin implements Plugin {
private readonly logger: Logger;
@@ -43,6 +44,9 @@ export class CloudDefendPlugin implements Plugin
@@ -67,14 +84,25 @@ const getHealthyAgents = async (
const calculateCloudDefendStatusCode = (
indicesStatus: {
alerts: IndexStatus;
+ process: IndexStatus;
+ file: IndexStatus;
},
installedCloudDefendPackagePolicies: number,
healthyAgents: number,
timeSinceInstallationInMinutes: number
): CloudDefendStatusCode => {
- // We check privileges only for the relevant indices for our pages to appear
- if (indicesStatus.alerts === 'unprivileged') return 'unprivileged';
- if (indicesStatus.alerts === 'not-empty') return 'indexed';
+ if (
+ indicesStatus.alerts === 'unprivileged' ||
+ indicesStatus.file === 'unprivileged' ||
+ indicesStatus.process === 'unprivileged'
+ )
+ return 'unprivileged';
+ if (
+ indicesStatus.alerts === 'not-empty' ||
+ indicesStatus.file === 'not-empty' ||
+ indicesStatus.process === 'not-empty'
+ )
+ return 'indexed';
if (installedCloudDefendPackagePolicies === 0) return 'not-installed';
if (healthyAgents === 0) return 'not-deployed';
if (timeSinceInstallationInMinutes <= INDEX_TIMEOUT_IN_MINUTES) return 'indexing';
@@ -95,7 +123,7 @@ const assertResponse = (
}
};
-const getCloudDefendStatus = async ({
+export const getCloudDefendStatus = async ({
logger,
esClient,
soClient,
@@ -103,15 +131,19 @@ const getCloudDefendStatus = async ({
packagePolicyService,
agentPolicyService,
agentService,
-}: CloudDefendApiRequestHandlerContext): Promise => {
+}: CloudDefendStatusDependencies): Promise => {
const [
alertsIndexStatus,
+ fileIndexStatus,
+ processIndexStatus,
installation,
latestCloudDefendPackage,
installedPackagePolicies,
installedPolicyTemplates,
] = await Promise.all([
- checkIndexStatus(esClient.asCurrentUser, ALERTS_INDEX_PATTERN, logger),
+ checkIndexStatus(esClient, ALERTS_INDEX_PATTERN_DEFAULT_NS, logger),
+ checkIndexStatus(esClient, FILE_INDEX_PATTERN_DEFAULT_NS, logger),
+ checkIndexStatus(esClient, PROCESS_INDEX_PATTERN_DEFAULT_NS, logger),
packageService.asInternalUser.getInstallation(INTEGRATION_PACKAGE_NAME),
packageService.asInternalUser.fetchFindLatestPackage(INTEGRATION_PACKAGE_NAME),
getCloudDefendPackagePolicies(soClient, packagePolicyService, INTEGRATION_PACKAGE_NAME, {
@@ -134,14 +166,24 @@ const getCloudDefendStatus = async ({
const MIN_DATE = 0;
const indicesDetails = [
{
- index: ALERTS_INDEX_PATTERN,
+ index: ALERTS_INDEX_PATTERN_DEFAULT_NS,
status: alertsIndexStatus,
},
+ {
+ index: FILE_INDEX_PATTERN_DEFAULT_NS,
+ status: fileIndexStatus,
+ },
+ {
+ index: PROCESS_INDEX_PATTERN_DEFAULT_NS,
+ status: processIndexStatus,
+ },
];
const status = calculateCloudDefendStatusCode(
{
alerts: alertsIndexStatus,
+ file: fileIndexStatus,
+ process: processIndexStatus,
},
installedPackagePoliciesTotal,
healthyAgents,
@@ -183,7 +225,10 @@ export const defineGetCloudDefendStatusRoute = (router: CloudDefendRouter) =>
.addVersion({ version: '1', validate: {} }, async (context, request, response) => {
const cloudDefendContext = await context.cloudDefend;
try {
- const status = await getCloudDefendStatus(cloudDefendContext);
+ const status = await getCloudDefendStatus({
+ ...cloudDefendContext,
+ esClient: cloudDefendContext.esClient.asCurrentUser,
+ });
return response.ok({
body: status,
});
diff --git a/x-pack/plugins/cloud_defend/server/types.ts b/x-pack/plugins/cloud_defend/server/types.ts
index 121a97ee926be..e6a5d9454ba81 100644
--- a/x-pack/plugins/cloud_defend/server/types.ts
+++ b/x-pack/plugins/cloud_defend/server/types.ts
@@ -27,6 +27,8 @@ import type {
PluginStart as DataPluginStart,
} from '@kbn/data-plugin/server';
+import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface CloudDefendPluginSetup {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
@@ -36,6 +38,7 @@ export interface CloudDefendPluginSetupDeps {
data: DataPluginSetup;
security: SecurityPluginSetup;
cloud: CloudSetup;
+ usageCollection?: UsageCollectionSetup;
}
export interface CloudDefendPluginStartDeps {
data: DataPluginStart;
diff --git a/x-pack/plugins/cloud_defend/tsconfig.json b/x-pack/plugins/cloud_defend/tsconfig.json
index d1a3eaa60681f..f2433e1c956a0 100755
--- a/x-pack/plugins/cloud_defend/tsconfig.json
+++ b/x-pack/plugins/cloud_defend/tsconfig.json
@@ -34,7 +34,8 @@
"@kbn/utility-types",
"@kbn/utility-types-jest",
"@kbn/kubernetes-security-plugin",
- "@kbn/core-http-router-server-mocks"
+ "@kbn/core-http-router-server-mocks",
+ "@kbn/core-elasticsearch-server"
],
"exclude": ["target/**/*"]
}
diff --git a/x-pack/plugins/cloud_integrations/cloud_data_migration/server/config.ts b/x-pack/plugins/cloud_integrations/cloud_data_migration/server/config.ts
index d1b9842857d47..e6a7fce2541f2 100644
--- a/x-pack/plugins/cloud_integrations/cloud_data_migration/server/config.ts
+++ b/x-pack/plugins/cloud_integrations/cloud_data_migration/server/config.ts
@@ -9,7 +9,14 @@ import { schema, TypeOf } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core-plugins-server';
const configSchema = schema.object({
- enabled: schema.boolean({ defaultValue: true }),
+ enabled: schema.conditional(
+ schema.contextRef('serverless'),
+ true,
+ // cloud_data_migration is disabled in serverless; refer to the serverless.yml file as the source of truth
+ // We take this approach in order to have a central place (serverless.yml) to view disabled plugins across Kibana
+ schema.boolean({ defaultValue: true }),
+ schema.never()
+ ),
});
export type CloudDataMigrationConfig = TypeOf;
diff --git a/x-pack/plugins/cross_cluster_replication/server/config.ts b/x-pack/plugins/cross_cluster_replication/server/config.ts
index 4cba6d0707abb..1d83f53920576 100644
--- a/x-pack/plugins/cross_cluster_replication/server/config.ts
+++ b/x-pack/plugins/cross_cluster_replication/server/config.ts
@@ -26,7 +26,14 @@ const schemaLatest = schema.object(
* Disables the plugin.
* Added back in 8.8.
*/
- enabled: schema.boolean({ defaultValue: true }),
+ enabled: schema.conditional(
+ schema.contextRef('serverless'),
+ true,
+ // CCR is disabled in serverless; refer to the serverless.yml file as the source of truth
+ // We take this approach in order to have a central place (serverless.yml) to view disabled plugins across Kibana
+ schema.boolean({ defaultValue: true }),
+ schema.never()
+ ),
},
{ defaultValue: undefined }
);
diff --git a/x-pack/plugins/fleet/common/services/agent_policies_helpers.ts b/x-pack/plugins/fleet/common/services/agent_policies_helpers.ts
index 9db799997fad3..52ce24634886e 100644
--- a/x-pack/plugins/fleet/common/services/agent_policies_helpers.ts
+++ b/x-pack/plugins/fleet/common/services/agent_policies_helpers.ts
@@ -6,7 +6,7 @@
*/
import type { AgentPolicy } from '../types';
-import { FLEET_SERVER_PACKAGE, FLEET_APM_PACKAGE } from '../constants';
+import { FLEET_SERVER_PACKAGE, FLEET_APM_PACKAGE, FLEET_SYNTHETICS_PACKAGE } from '../constants';
export function policyHasFleetServer(agentPolicy: AgentPolicy) {
if (!agentPolicy.package_policies) {
@@ -19,8 +19,17 @@ export function policyHasFleetServer(agentPolicy: AgentPolicy) {
}
export function policyHasAPMIntegration(agentPolicy: AgentPolicy) {
+ return policyHasIntegration(agentPolicy, FLEET_APM_PACKAGE);
+}
+
+export function policyHasSyntheticsIntegration(agentPolicy: AgentPolicy) {
+ return policyHasIntegration(agentPolicy, FLEET_SYNTHETICS_PACKAGE);
+}
+
+function policyHasIntegration(agentPolicy: AgentPolicy, packageName: string) {
if (!agentPolicy.package_policies) {
return false;
}
- return agentPolicy.package_policies?.some((p) => p.package?.name === FLEET_APM_PACKAGE);
+
+ return agentPolicy.package_policies?.some((p) => p.package?.name === packageName);
}
diff --git a/x-pack/plugins/fleet/common/services/index.ts b/x-pack/plugins/fleet/common/services/index.ts
index 6b392f506b4c6..abf06ac54b07c 100644
--- a/x-pack/plugins/fleet/common/services/index.ts
+++ b/x-pack/plugins/fleet/common/services/index.ts
@@ -63,7 +63,11 @@ export {
export { getAllowedOutputTypeForPolicy } from './output_helpers';
export { agentStatusesToSummary } from './agent_statuses_to_summary';
-export { policyHasFleetServer, policyHasAPMIntegration } from './agent_policies_helpers';
+export {
+ policyHasFleetServer,
+ policyHasAPMIntegration,
+ policyHasSyntheticsIntegration,
+} from './agent_policies_helpers';
export {
generateNewAgentPolicyWithDefaults,
diff --git a/x-pack/plugins/fleet/common/services/output_helpers.ts b/x-pack/plugins/fleet/common/services/output_helpers.ts
index d0d8c826878fd..00b480c378b61 100644
--- a/x-pack/plugins/fleet/common/services/output_helpers.ts
+++ b/x-pack/plugins/fleet/common/services/output_helpers.ts
@@ -6,7 +6,12 @@
*/
import type { AgentPolicy } from '../types';
-import { FLEET_APM_PACKAGE, FLEET_SERVER_PACKAGE, outputType } from '../constants';
+import {
+ FLEET_APM_PACKAGE,
+ FLEET_SERVER_PACKAGE,
+ FLEET_SYNTHETICS_PACKAGE,
+ outputType,
+} from '../constants';
/**
* Return allowed output type for a given agent policy,
@@ -16,7 +21,10 @@ export function getAllowedOutputTypeForPolicy(agentPolicy: AgentPolicy) {
const isRestrictedToSameClusterES =
agentPolicy.package_policies &&
agentPolicy.package_policies.some(
- (p) => p.package?.name === FLEET_APM_PACKAGE || p.package?.name === FLEET_SERVER_PACKAGE
+ (p) =>
+ p.package?.name === FLEET_APM_PACKAGE ||
+ p.package?.name === FLEET_SERVER_PACKAGE ||
+ p.package?.name === FLEET_SYNTHETICS_PACKAGE
);
if (isRestrictedToSameClusterES) {
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/hooks.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/hooks.test.tsx
index 1a415e51e23a6..2d7eef6b864bf 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/hooks.test.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/hooks.test.tsx
@@ -130,7 +130,7 @@ describe('useOutputOptions', () => {
size="s"
>
{
size="s"
>
{
size="s"
>
{
size="s"
>
{
size="s"
>
{
size="s"
>
{
size="s"
>
{
size="s"
>
getAllowedOutputTypeForPolicy(agentPolicy as AgentPolicy),
[agentPolicy]
@@ -89,7 +90,7 @@ export function useOutputOptions(agentPolicy: Partial
) : undefined
),
- disabled: !isLicenceAllowingPolicyPerOutput || isOutputTypeUnsupported,
+ disabled: !isPolicyPerOutputAllowed || isOutputTypeUnsupported,
};
}),
];
- }, [outputsRequest, isLicenceAllowingPolicyPerOutput, allowedOutputTypes]);
+ }, [outputsRequest, isPolicyPerOutputAllowed, allowedOutputTypes]);
const monitoringOutputOptions = useMemo(() => {
if (outputsRequest.isLoading || !outputsRequest.data) {
@@ -135,11 +136,11 @@ export function useOutputOptions(agentPolicy: Partial ({
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/confirm_update.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/confirm_update.tsx
index 8d96c5f314547..4157c6964f79a 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/confirm_update.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/confirm_update.tsx
@@ -73,13 +73,13 @@ const ConfirmDescription: React.FunctionComponent = ({
title={
}
>
{' '}
>
diff --git a/x-pack/plugins/fleet/server/integration_tests/__snapshots__/cloud_preconfiguration.test.ts.snap b/x-pack/plugins/fleet/server/integration_tests/__snapshots__/cloud_preconfiguration.test.ts.snap
deleted file mode 100644
index 6a9de18956e43..0000000000000
--- a/x-pack/plugins/fleet/server/integration_tests/__snapshots__/cloud_preconfiguration.test.ts.snap
+++ /dev/null
@@ -1,258 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Fleet preconfiguration reset Preconfigured cloud policy With a full preconfigured cloud policy Create correct .fleet-policies 1`] = `
-Object {
- "agent": Object {
- "download": Object {
- "sourceURI": "https://artifacts.elastic.co/downloads/",
- },
- "features": Object {},
- "monitoring": Object {
- "enabled": false,
- "logs": false,
- "metrics": false,
- },
- "protection": Object {
- "enabled": false,
- "signing_key": "",
- "uninstall_token_hash": "",
- },
- },
- "id": "policy-elastic-agent-on-cloud",
- "inputs": Array [
- Object {
- "data_stream": Object {
- "namespace": "default",
- },
- "id": "fleet-server-fleet_server-elastic-cloud-fleet-server",
- "meta": Object {
- "package": Object {
- "name": "fleet_server",
- },
- },
- "name": "Fleet Server",
- "package_policy_id": "elastic-cloud-fleet-server",
- "revision": 1,
- "server.runtime": Object {
- "gc_percent": 20,
- },
- "type": "fleet-server",
- "unused_key": "not_used",
- "use_output": "es-containerhost",
- },
- Object {
- "apm-server": Object {
- "agent": Object {
- "config": Object {
- "elasticsearch": Object {
- "api_key": "",
- },
- },
- },
- "agent_config": Array [],
- "auth": Object {
- "anonymous": Object {
- "allow_agent": Array [
- "rum-js",
- "js-base",
- "iOS/swift",
- ],
- "allow_service": null,
- "enabled": true,
- "rate_limit": Object {
- "event_limit": 300,
- "ip_limit": 1000,
- },
- },
- "api_key": Object {
- "enabled": true,
- "limit": 100,
- },
- "secret_token": "CLOUD_SECRET_TOKEN",
- },
- "capture_personal_data": true,
- "default_service_environment": null,
- "expvar.enabled": false,
- "host": "0.0.0.0:8200",
- "idle_timeout": "45s",
- "java_attacher": Object {
- "discovery-rules": null,
- "download-agent-version": null,
- "enabled": false,
- },
- "max_connections": 0,
- "max_event_size": 307200,
- "max_header_size": 1048576,
- "pprof.enabled": false,
- "read_timeout": "3600s",
- "response_headers": null,
- "rum": Object {
- "allow_headers": null,
- "allow_origins": Array [
- "*",
- ],
- "enabled": true,
- "exclude_from_grouping": "^/webpack",
- "library_pattern": "node_modules|bower_components|~",
- "response_headers": null,
- "source_mapping": Object {
- "elasticsearch": Object {
- "api_key": "",
- },
- "metadata": Array [],
- },
- },
- "sampling": Object {
- "tail": Object {
- "enabled": false,
- "interval": "1m",
- "policies": Array [
- Object {
- "sample_rate": 0.1,
- },
- ],
- "storage_limit": "3GB",
- },
- },
- "shutdown_timeout": "30s",
- "ssl": Object {
- "certificate": "/app/config/certs/node.crt",
- "cipher_suites": null,
- "curve_types": null,
- "enabled": true,
- "key": "/app/config/certs/node.key",
- "key_passphrase": null,
- "supported_protocols": Array [
- "TLSv1.1",
- "TLSv1.2",
- "TLSv1.3",
- ],
- },
- "write_timeout": "30s",
- },
- "data_stream": Object {
- "namespace": "default",
- },
- "id": "elastic-cloud-apm",
- "meta": Object {
- "package": Object {
- "name": "apm",
- },
- },
- "name": "Elastic APM",
- "package_policy_id": "elastic-cloud-apm",
- "revision": 2,
- "type": "apm",
- "use_output": "es-containerhost",
- },
- ],
- "output_permissions": Object {
- "es-containerhost": Object {
- "_elastic_agent_checks": Object {
- "cluster": Array [
- "monitor",
- ],
- },
- "_elastic_agent_monitoring": Object {
- "indices": Array [],
- },
- "elastic-cloud-apm": Object {
- "cluster": Array [
- "cluster:monitor/main",
- ],
- "indices": Array [
- Object {
- "names": Array [
- "logs-apm.app-default",
- ],
- "privileges": Array [
- "auto_configure",
- "create_doc",
- ],
- },
- Object {
- "names": Array [
- "metrics-apm.app.*-default",
- ],
- "privileges": Array [
- "auto_configure",
- "create_doc",
- ],
- },
- Object {
- "names": Array [
- "logs-apm.error-default",
- ],
- "privileges": Array [
- "auto_configure",
- "create_doc",
- ],
- },
- Object {
- "names": Array [
- "metrics-apm.internal-default",
- ],
- "privileges": Array [
- "auto_configure",
- "create_doc",
- ],
- },
- Object {
- "names": Array [
- "metrics-apm.profiling-default",
- ],
- "privileges": Array [
- "auto_configure",
- "create_doc",
- ],
- },
- Object {
- "names": Array [
- "traces-apm.rum-default",
- ],
- "privileges": Array [
- "auto_configure",
- "create_doc",
- ],
- },
- Object {
- "names": Array [
- "traces-apm.sampled-default",
- ],
- "privileges": Array [
- "auto_configure",
- "create_doc",
- "maintenance",
- "monitor",
- "read",
- ],
- },
- Object {
- "names": Array [
- "traces-apm-default",
- ],
- "privileges": Array [
- "auto_configure",
- "create_doc",
- ],
- },
- ],
- },
- },
- },
- "outputs": Object {
- "es-containerhost": Object {
- "hosts": Array [
- "https://cloudinternales:9200",
- ],
- "type": "elasticsearch",
- },
- },
- "revision": 5,
- "secret_references": Array [],
- "signed": Object {
- "data": "",
- "signature": "",
- },
-}
-`;
diff --git a/x-pack/plugins/fleet/server/integration_tests/cloud_preconfiguration.test.ts b/x-pack/plugins/fleet/server/integration_tests/cloud_preconfiguration.test.ts
index 7c18ef95997f6..7da8edb68f9f7 100644
--- a/x-pack/plugins/fleet/server/integration_tests/cloud_preconfiguration.test.ts
+++ b/x-pack/plugins/fleet/server/integration_tests/cloud_preconfiguration.test.ts
@@ -164,7 +164,201 @@ describe('Fleet preconfiguration reset', () => {
data.signed.data = '';
data.signed.signature = '';
- expect(data).toMatchSnapshot();
+ expect(data).toEqual({
+ agent: {
+ download: {
+ sourceURI: 'https://artifacts.elastic.co/downloads/',
+ },
+ features: {},
+ monitoring: {
+ enabled: false,
+ logs: false,
+ metrics: false,
+ },
+ protection: {
+ enabled: false,
+ signing_key: '',
+ uninstall_token_hash: '',
+ },
+ },
+ id: 'policy-elastic-agent-on-cloud',
+ inputs: [
+ {
+ data_stream: {
+ namespace: 'default',
+ },
+ id: 'fleet-server-fleet_server-elastic-cloud-fleet-server',
+ meta: {
+ package: {
+ name: 'fleet_server',
+ },
+ },
+ name: 'Fleet Server',
+ package_policy_id: 'elastic-cloud-fleet-server',
+ revision: 1,
+ 'server.runtime': {
+ gc_percent: 20,
+ },
+ type: 'fleet-server',
+ unused_key: 'not_used',
+ use_output: 'es-containerhost',
+ },
+ {
+ 'apm-server': {
+ agent: {
+ config: {
+ elasticsearch: {
+ api_key: '',
+ },
+ },
+ },
+ agent_config: [],
+ auth: {
+ anonymous: {
+ allow_agent: ['rum-js', 'js-base', 'iOS/swift'],
+ allow_service: null,
+ enabled: true,
+ rate_limit: {
+ event_limit: 300,
+ ip_limit: 1000,
+ },
+ },
+ api_key: {
+ enabled: true,
+ limit: 100,
+ },
+ secret_token: 'CLOUD_SECRET_TOKEN',
+ },
+ capture_personal_data: true,
+ default_service_environment: null,
+ 'expvar.enabled': false,
+ host: '0.0.0.0:8200',
+ idle_timeout: '45s',
+ java_attacher: {
+ 'discovery-rules': null,
+ 'download-agent-version': null,
+ enabled: false,
+ },
+ max_connections: 0,
+ max_event_size: 307200,
+ max_header_size: 1048576,
+ 'pprof.enabled': false,
+ read_timeout: '3600s',
+ response_headers: null,
+ rum: {
+ allow_headers: null,
+ allow_origins: ['*'],
+ enabled: true,
+ exclude_from_grouping: '^/webpack',
+ library_pattern: 'node_modules|bower_components|~',
+ response_headers: null,
+ source_mapping: {
+ elasticsearch: {
+ api_key: '',
+ },
+ metadata: [],
+ },
+ },
+ sampling: {
+ tail: {
+ enabled: false,
+ interval: '1m',
+ policies: [
+ {
+ sample_rate: 0.1,
+ },
+ ],
+ storage_limit: '3GB',
+ },
+ },
+ shutdown_timeout: '30s',
+ ssl: {
+ certificate: '/app/config/certs/node.crt',
+ cipher_suites: null,
+ curve_types: null,
+ enabled: true,
+ key: '/app/config/certs/node.key',
+ key_passphrase: null,
+ supported_protocols: ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'],
+ },
+ write_timeout: '30s',
+ },
+ data_stream: {
+ namespace: 'default',
+ },
+ id: 'elastic-cloud-apm',
+ meta: {
+ package: {
+ name: 'apm',
+ },
+ },
+ name: 'Elastic APM',
+ package_policy_id: 'elastic-cloud-apm',
+ revision: 2,
+ type: 'apm',
+ use_output: 'es-containerhost',
+ },
+ ],
+ output_permissions: {
+ 'es-containerhost': {
+ _elastic_agent_checks: {
+ cluster: ['monitor'],
+ },
+ _elastic_agent_monitoring: {
+ indices: [],
+ },
+ 'elastic-cloud-apm': {
+ cluster: ['cluster:monitor/main'],
+ indices: [
+ {
+ names: ['logs-apm.app-default'],
+ privileges: ['auto_configure', 'create_doc'],
+ },
+ {
+ names: ['metrics-apm.app.*-default'],
+ privileges: ['auto_configure', 'create_doc'],
+ },
+ {
+ names: ['logs-apm.error-default'],
+ privileges: ['auto_configure', 'create_doc'],
+ },
+ {
+ names: ['metrics-apm.internal-default'],
+ privileges: ['auto_configure', 'create_doc'],
+ },
+ {
+ names: ['metrics-apm.profiling-default'],
+ privileges: ['auto_configure', 'create_doc'],
+ },
+ {
+ names: ['traces-apm.rum-default'],
+ privileges: ['auto_configure', 'create_doc'],
+ },
+ {
+ names: ['traces-apm.sampled-default'],
+ privileges: ['auto_configure', 'create_doc', 'maintenance', 'monitor', 'read'],
+ },
+ {
+ names: ['traces-apm-default'],
+ privileges: ['auto_configure', 'create_doc'],
+ },
+ ],
+ },
+ },
+ },
+ outputs: {
+ 'es-containerhost': {
+ hosts: ['https://cloudinternales:9200'],
+ type: 'elasticsearch',
+ },
+ },
+ revision: 5,
+ secret_references: [],
+ signed: {
+ data: '',
+ signature: '',
+ },
+ });
});
it('Create correct package policies', async () => {
diff --git a/x-pack/plugins/fleet/server/services/agent_policies/output_helpers.test.ts b/x-pack/plugins/fleet/server/services/agent_policies/output_helpers.test.ts
index 29d48d5d595ef..e43bc275a9c4d 100644
--- a/x-pack/plugins/fleet/server/services/agent_policies/output_helpers.test.ts
+++ b/x-pack/plugins/fleet/server/services/agent_policies/output_helpers.test.ts
@@ -196,7 +196,7 @@ describe('validateOutputForPolicy', () => {
);
});
- it('should not allow logstash output to be used with a policy using fleet server or APM', async () => {
+ it('should not allow logstash output to be used with a policy using fleet server, synthetics or APM', async () => {
mockHasLicence(true);
mockedOutputService.get.mockResolvedValue({
type: 'logstash',
@@ -217,7 +217,7 @@ describe('validateOutputForPolicy', () => {
);
});
- it('should allow elasticsearch output to be used with a policy using fleet server or APM', async () => {
+ it('should allow elasticsearch output to be used with a policy using fleet server, synthetics or APM', async () => {
mockHasLicence(true);
mockedOutputService.get.mockResolvedValue({
type: 'elasticsearch',
diff --git a/x-pack/plugins/fleet/server/services/agent_policies/outputs_helpers.ts b/x-pack/plugins/fleet/server/services/agent_policies/outputs_helpers.ts
index d93bb965295ef..bbe00c49b414f 100644
--- a/x-pack/plugins/fleet/server/services/agent_policies/outputs_helpers.ts
+++ b/x-pack/plugins/fleet/server/services/agent_policies/outputs_helpers.ts
@@ -9,7 +9,7 @@ import type { SavedObjectsClientContract } from '@kbn/core/server';
import type { AgentPolicySOAttributes, AgentPolicy } from '../../types';
import { LICENCE_FOR_PER_POLICY_OUTPUT, outputType } from '../../../common/constants';
-import { policyHasFleetServer } from '../../../common/services';
+import { policyHasFleetServer, policyHasSyntheticsIntegration } from '../../../common/services';
import { appContextService } from '..';
import { outputService } from '../output';
import { OutputInvalidError, OutputLicenceError } from '../../errors';
@@ -80,6 +80,9 @@ export async function validateOutputForPolicy(
// Validate output when the policy has fleet server
if (policyHasFleetServer(data as AgentPolicy)) return;
+ // Validate output when the policy has synthetics integration
+ if (policyHasSyntheticsIntegration(data as AgentPolicy)) return;
+
const hasLicence = appContextService
.getSecurityLicense()
.hasAtLeast(LICENCE_FOR_PER_POLICY_OUTPUT);
diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts
index d32737e0eb5c1..6958ea80c00d6 100644
--- a/x-pack/plugins/fleet/server/services/agent_policy.ts
+++ b/x-pack/plugins/fleet/server/services/agent_policy.ts
@@ -48,6 +48,7 @@ import {
packageToPackagePolicy,
policyHasFleetServer,
policyHasAPMIntegration,
+ policyHasSyntheticsIntegration,
} from '../../common/services';
import {
agentPolicyStatuses,
@@ -211,6 +212,10 @@ class AgentPolicyService {
return policyHasFleetServer(agentPolicy);
}
+ public hasSyntheticsIntegration(agentPolicy: AgentPolicy) {
+ return policyHasSyntheticsIntegration(agentPolicy);
+ }
+
public async create(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
diff --git a/x-pack/plugins/fleet/server/services/output.test.ts b/x-pack/plugins/fleet/server/services/output.test.ts
index 7c0076abfc653..5ecd3a4a29a40 100644
--- a/x-pack/plugins/fleet/server/services/output.test.ts
+++ b/x-pack/plugins/fleet/server/services/output.test.ts
@@ -201,7 +201,7 @@ function getMockedSoClient(
describe('Output Service', () => {
const esClientMock = elasticsearchServiceMock.createElasticsearchClient();
- const mockedAgentPolicyResolvedValue = {
+ const mockedAgentPolicyWithFleetServerResolvedValue = {
items: [
{
name: 'fleet server policy',
@@ -232,18 +232,50 @@ describe('Output Service', () => {
],
} as unknown as ReturnType;
+ const mockedAgentPolicyWithSyntheticsResolvedValue = {
+ items: [
+ {
+ name: 'synthetics policy',
+ id: 'synthetics_policy',
+ package_policies: [
+ {
+ name: 'synthetics-123',
+ package: {
+ name: 'synthetics',
+ },
+ },
+ ],
+ },
+ {
+ name: 'agent policy 1',
+ id: 'agent_policy_1',
+ is_managed: false,
+ package_policies: [
+ {
+ name: 'nginx',
+ package: {
+ name: 'nginx',
+ },
+ },
+ ],
+ },
+ ],
+ } as unknown as ReturnType;
+
beforeEach(() => {
mockedAgentPolicyService.list.mockClear();
mockedAgentPolicyService.hasAPMIntegration.mockClear();
mockedAgentPolicyService.hasFleetServerIntegration.mockClear();
+ mockedAgentPolicyService.hasSyntheticsIntegration.mockClear();
mockedAgentPolicyService.removeOutputFromAll.mockReset();
mockedAppContextService.getInternalUserSOClient.mockReset();
mockedAppContextService.getEncryptedSavedObjectsSetup.mockReset();
mockedAuditLoggingService.writeCustomSoAuditLog.mockReset();
mockedAgentPolicyService.update.mockReset();
});
+
describe('create', () => {
- it('work with a predefined id', async () => {
+ it('works with a predefined id', async () => {
const soClient = getMockedSoClient();
await outputService.create(
@@ -446,7 +478,9 @@ describe('Output Service', () => {
mockedAppContextService.getEncryptedSavedObjectsSetup.mockReturnValue({
canEncrypt: true,
} as any);
- mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyResolvedValue);
+ mockedAgentPolicyService.list.mockResolvedValue(
+ mockedAgentPolicyWithFleetServerResolvedValue
+ );
mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true);
await outputService.create(
@@ -470,6 +504,37 @@ describe('Output Service', () => {
);
});
+ it('should update synthetics policies with data_output_id=default_output_id if a new default logstash output is created', async () => {
+ const soClient = getMockedSoClient({
+ defaultOutputId: 'output-test',
+ });
+ mockedAppContextService.getEncryptedSavedObjectsSetup.mockReturnValue({
+ canEncrypt: true,
+ } as any);
+ mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyWithSyntheticsResolvedValue);
+ mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(true);
+
+ await outputService.create(
+ soClient,
+ esClientMock,
+ {
+ is_default: true,
+ is_default_monitoring: false,
+ name: 'Test',
+ type: 'logstash',
+ },
+ { id: 'output-1' }
+ );
+
+ expect(mockedAgentPolicyService.update).toBeCalledWith(
+ expect.anything(),
+ expect.anything(),
+ 'synthetics_policy',
+ { data_output_id: 'output-test' },
+ { force: false }
+ );
+ });
+
it('Should allow to create a new logstash output with no errors if is not set as default', async () => {
const soClient = getMockedSoClient({
defaultOutputId: 'output-test',
@@ -477,7 +542,9 @@ describe('Output Service', () => {
mockedAppContextService.getEncryptedSavedObjectsSetup.mockReturnValue({
canEncrypt: true,
} as any);
- mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyResolvedValue);
+ mockedAgentPolicyService.list.mockResolvedValue(
+ mockedAgentPolicyWithFleetServerResolvedValue
+ );
mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true);
await outputService.create(
@@ -523,7 +590,9 @@ describe('Output Service', () => {
mockedAppContextService.getEncryptedSavedObjectsSetup.mockReturnValue({
canEncrypt: true,
} as any);
- mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyResolvedValue);
+ mockedAgentPolicyService.list.mockResolvedValue(
+ mockedAgentPolicyWithFleetServerResolvedValue
+ );
mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true);
await outputService.create(
@@ -547,6 +616,37 @@ describe('Output Service', () => {
);
});
+ it('Should update synthetics policies with data_output_id=default_output_id if a new default kafka output is created', async () => {
+ const soClient = getMockedSoClient({
+ defaultOutputId: 'output-test',
+ });
+ mockedAppContextService.getEncryptedSavedObjectsSetup.mockReturnValue({
+ canEncrypt: true,
+ } as any);
+ mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyWithSyntheticsResolvedValue);
+ mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(true);
+
+ await outputService.create(
+ soClient,
+ esClientMock,
+ {
+ is_default: true,
+ is_default_monitoring: false,
+ name: 'Test',
+ type: 'kafka',
+ },
+ { id: 'output-1' }
+ );
+
+ expect(mockedAgentPolicyService.update).toBeCalledWith(
+ expect.anything(),
+ expect.anything(),
+ 'synthetics_policy',
+ { data_output_id: 'output-test' },
+ { force: false }
+ );
+ });
+
it('Should allow to create a new kafka output with no errors if is not set as default', async () => {
const soClient = getMockedSoClient({
defaultOutputId: 'output-test',
@@ -554,7 +654,9 @@ describe('Output Service', () => {
mockedAppContextService.getEncryptedSavedObjectsSetup.mockReturnValue({
canEncrypt: true,
} as any);
- mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyResolvedValue);
+ mockedAgentPolicyService.list.mockResolvedValue(
+ mockedAgentPolicyWithFleetServerResolvedValue
+ );
mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true);
await outputService.create(
@@ -878,6 +980,7 @@ describe('Output Service', () => {
} as unknown as ReturnType);
mockedAgentPolicyService.hasAPMIntegration.mockReturnValue(false);
mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(false);
+ mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(false);
await outputService.update(soClient, esClientMock, 'existing-es-output', {
type: 'logstash',
@@ -936,36 +1039,9 @@ describe('Output Service', () => {
const soClient = getMockedSoClient({
defaultOutputId: 'output-test',
});
- mockedAgentPolicyService.list.mockResolvedValue({
- items: [
- {
- name: 'fleet server policy',
- id: 'fleet_server_policy',
- is_default_fleet_server: true,
- package_policies: [
- {
- name: 'fleet-server-123',
- package: {
- name: 'fleet_server',
- },
- },
- ],
- },
- {
- name: 'agent policy 1',
- id: 'agent_policy_1',
- is_managed: false,
- package_policies: [
- {
- name: 'nginx',
- package: {
- name: 'nginx',
- },
- },
- ],
- },
- ],
- } as unknown as ReturnType);
+ mockedAgentPolicyService.list.mockResolvedValue(
+ mockedAgentPolicyWithFleetServerResolvedValue
+ );
mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true);
await outputService.update(soClient, esClientMock, 'output-test', {
@@ -994,36 +1070,9 @@ describe('Output Service', () => {
const soClient = getMockedSoClient({
defaultOutputId: 'output-test',
});
- mockedAgentPolicyService.list.mockResolvedValue({
- items: [
- {
- name: 'fleet server policy',
- id: 'fleet_server_policy',
- is_default_fleet_server: true,
- package_policies: [
- {
- name: 'fleet-server-123',
- package: {
- name: 'fleet_server',
- },
- },
- ],
- },
- {
- name: 'agent policy 1',
- id: 'agent_policy_1',
- is_managed: false,
- package_policies: [
- {
- name: 'nginx',
- package: {
- name: 'nginx',
- },
- },
- ],
- },
- ],
- } as unknown as ReturnType);
+ mockedAgentPolicyService.list.mockResolvedValue(
+ mockedAgentPolicyWithFleetServerResolvedValue
+ );
mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true);
await outputService.update(
@@ -1056,38 +1105,77 @@ describe('Output Service', () => {
);
});
+ it('should update synthetics policies with data_output_id=default_output_id if a default ES output is changed to logstash', async () => {
+ const soClient = getMockedSoClient({
+ defaultOutputId: 'output-test',
+ });
+ mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyWithSyntheticsResolvedValue);
+ mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(true);
+
+ await outputService.update(soClient, esClientMock, 'output-test', {
+ type: 'logstash',
+ hosts: ['test:4343'],
+ is_default: true,
+ });
+
+ expect(soClient.update).toBeCalledWith(expect.anything(), expect.anything(), {
+ type: 'logstash',
+ hosts: ['test:4343'],
+ is_default: true,
+ ca_sha256: null,
+ ca_trusted_fingerprint: null,
+ });
+ expect(mockedAgentPolicyService.update).toBeCalledWith(
+ expect.anything(),
+ expect.anything(),
+ 'synthetics_policy',
+ { data_output_id: 'output-test' },
+ { force: false }
+ );
+ });
+
+ it('should update synthetics policies with data_output_id=default_output_id and force=true if a default ES output is changed to logstash, from preconfiguration', async () => {
+ const soClient = getMockedSoClient({
+ defaultOutputId: 'output-test',
+ });
+ mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyWithSyntheticsResolvedValue);
+ mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(true);
+
+ await outputService.update(
+ soClient,
+ esClientMock,
+ 'output-test',
+ {
+ type: 'logstash',
+ hosts: ['test:4343'],
+ is_default: true,
+ },
+ {
+ fromPreconfiguration: true,
+ }
+ );
+
+ expect(soClient.update).toBeCalledWith(expect.anything(), expect.anything(), {
+ type: 'logstash',
+ hosts: ['test:4343'],
+ is_default: true,
+ ca_sha256: null,
+ ca_trusted_fingerprint: null,
+ });
+ expect(mockedAgentPolicyService.update).toBeCalledWith(
+ expect.anything(),
+ expect.anything(),
+ 'synthetics_policy',
+ { data_output_id: 'output-test' },
+ { force: true }
+ );
+ });
+
it('Should return an error if trying to change the output to logstash for fleet server policy', async () => {
const soClient = getMockedSoClient({});
- mockedAgentPolicyService.list.mockResolvedValue({
- items: [
- {
- name: 'fleet server policy',
- id: 'fleet_server_policy',
- is_default_fleet_server: true,
- package_policies: [
- {
- name: 'fleet-server-123',
- package: {
- name: 'fleet_server',
- },
- },
- ],
- },
- {
- name: 'agent policy 1',
- id: 'agent_policy_1',
- is_managed: false,
- package_policies: [
- {
- name: 'nginx',
- package: {
- name: 'nginx',
- },
- },
- ],
- },
- ],
- } as unknown as ReturnType);
+ mockedAgentPolicyService.list.mockResolvedValue(
+ mockedAgentPolicyWithFleetServerResolvedValue
+ );
mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true);
await expect(
@@ -1100,6 +1188,22 @@ describe('Output Service', () => {
);
});
+ it('Should return an error if trying to change the output to logstash for synthetics policy', async () => {
+ const soClient = getMockedSoClient({});
+ mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyWithSyntheticsResolvedValue);
+ mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(false);
+ mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(true);
+
+ await expect(
+ outputService.update(soClient, esClientMock, 'existing-es-output', {
+ type: 'logstash',
+ hosts: ['test:4343'],
+ })
+ ).rejects.toThrowError(
+ 'Logstash output cannot be used with Synthetics integration in synthetics policy. Please create a new ElasticSearch output.'
+ );
+ });
+
it('should call audit logger', async () => {
const soClient = getMockedSoClient({ defaultOutputId: 'existing-es-output' });
@@ -1115,7 +1219,6 @@ describe('Output Service', () => {
});
// With Kafka output
-
it('Should delete ES specific fields if the output type changes to kafka', async () => {
const soClient = getMockedSoClient({});
mockedAgentPolicyService.list.mockResolvedValue({
@@ -1123,6 +1226,7 @@ describe('Output Service', () => {
} as unknown as ReturnType);
mockedAgentPolicyService.hasAPMIntegration.mockReturnValue(false);
mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(false);
+ mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(false);
await outputService.update(soClient, esClientMock, 'existing-es-output', {
type: 'kafka',
@@ -1180,7 +1284,9 @@ describe('Output Service', () => {
const soClient = getMockedSoClient({
defaultOutputId: 'output-test',
});
- mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyResolvedValue);
+ mockedAgentPolicyService.list.mockResolvedValue(
+ mockedAgentPolicyWithFleetServerResolvedValue
+ );
mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true);
await outputService.update(soClient, esClientMock, 'output-test', {
@@ -1218,7 +1324,9 @@ describe('Output Service', () => {
const soClient = getMockedSoClient({
defaultOutputId: 'output-test',
});
- mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyResolvedValue);
+ mockedAgentPolicyService.list.mockResolvedValue(
+ mockedAgentPolicyWithFleetServerResolvedValue
+ );
mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true);
await outputService.update(
@@ -1259,6 +1367,90 @@ describe('Output Service', () => {
{ force: true }
);
});
+
+ it('should update synthetics policies with data_output_id=default_output_id if a default ES output is changed to kafka', async () => {
+ const soClient = getMockedSoClient({
+ defaultOutputId: 'output-test',
+ });
+ mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyWithSyntheticsResolvedValue);
+ mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(true);
+
+ await outputService.update(soClient, esClientMock, 'output-test', {
+ type: 'kafka',
+ hosts: ['http://test:4343'],
+ is_default: true,
+ });
+
+ expect(soClient.update).toBeCalledWith(expect.anything(), expect.anything(), {
+ type: 'kafka',
+ hosts: ['http://test:4343'],
+ is_default: true,
+ ca_sha256: null,
+ ca_trusted_fingerprint: null,
+ client_id: 'Elastic Agent',
+ compression: 'gzip',
+ compression_level: 4,
+ partition: 'hash',
+ timeout: 30,
+ version: '1.0.0',
+ broker_timeout: 10,
+ broker_ack_reliability: 'Wait for local commit',
+ broker_buffer_size: 256,
+ });
+ expect(mockedAgentPolicyService.update).toBeCalledWith(
+ expect.anything(),
+ expect.anything(),
+ 'synthetics_policy',
+ { data_output_id: 'output-test' },
+ { force: false }
+ );
+ });
+
+ it('should update synthetics policies with data_output_id=default_output_id and force=true if a default ES output is changed to kafka, from preconfiguration', async () => {
+ const soClient = getMockedSoClient({
+ defaultOutputId: 'output-test',
+ });
+ mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyWithSyntheticsResolvedValue);
+ mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(true);
+
+ await outputService.update(
+ soClient,
+ esClientMock,
+ 'output-test',
+ {
+ type: 'kafka',
+ hosts: ['http://test:4343'],
+ is_default: true,
+ },
+ {
+ fromPreconfiguration: true,
+ }
+ );
+
+ expect(soClient.update).toBeCalledWith(expect.anything(), expect.anything(), {
+ type: 'kafka',
+ hosts: ['http://test:4343'],
+ is_default: true,
+ ca_sha256: null,
+ ca_trusted_fingerprint: null,
+ client_id: 'Elastic Agent',
+ compression: 'gzip',
+ compression_level: 4,
+ partition: 'hash',
+ timeout: 30,
+ version: '1.0.0',
+ broker_timeout: 10,
+ broker_ack_reliability: 'Wait for local commit',
+ broker_buffer_size: 256,
+ });
+ expect(mockedAgentPolicyService.update).toBeCalledWith(
+ expect.anything(),
+ expect.anything(),
+ 'synthetics_policy',
+ { data_output_id: 'output-test' },
+ { force: true }
+ );
+ });
});
describe('delete', () => {
diff --git a/x-pack/plugins/fleet/server/services/output.ts b/x-pack/plugins/fleet/server/services/output.ts
index a9e546d878fb5..ec5f63cbe3566 100644
--- a/x-pack/plugins/fleet/server/services/output.ts
+++ b/x-pack/plugins/fleet/server/services/output.ts
@@ -148,7 +148,7 @@ async function validateLogstashOutputNotUsedInAPMPolicy(
}
}
-async function findPoliciesWithFleetServer(
+async function findPoliciesWithFleetServerOrSynthetics(
soClient: SavedObjectsClientContract,
outputId?: string,
isDefault?: boolean
@@ -159,23 +159,24 @@ async function findPoliciesWithFleetServer(
? await getAgentPoliciesPerOutput(soClient, outputId, isDefault)
: (await agentPolicyService.list(soClient, { withPackagePolicies: true }))?.items;
- if (agentPolicies) {
- const policiesWithFleetServer = agentPolicies.filter((policy) =>
- agentPolicyService.hasFleetServerIntegration(policy)
- );
- return policiesWithFleetServer;
- }
- return [];
+ const policiesWithFleetServer =
+ agentPolicies?.filter((policy) => agentPolicyService.hasFleetServerIntegration(policy)) || [];
+ const policiesWithSynthetics =
+ agentPolicies?.filter((policy) => agentPolicyService.hasSyntheticsIntegration(policy)) || [];
+ return { policiesWithFleetServer, policiesWithSynthetics };
}
-function validateOutputNotUsedInFleetServerPolicy(
+function validateOutputNotUsedInPolicy(
agentPolicies: AgentPolicy[],
- dataOutputType: OutputType['Logstash'] | OutputType['Kafka']
+ dataOutputType: OutputType['Logstash'] | OutputType['Kafka'],
+ integrationName: string
) {
- // Validate no policy with fleet server use that policy
+ // Validate no policy with this integration uses that output
for (const agentPolicy of agentPolicies) {
throw new OutputInvalidError(
- `${_.capitalize(dataOutputType)} output cannot be used with Fleet Server integration in ${
+ `${_.capitalize(
+ dataOutputType
+ )} output cannot be used with ${integrationName} integration in ${
agentPolicy.name
}. Please create a new ElasticSearch output.`
);
@@ -192,44 +193,46 @@ async function validateTypeChanges(
fromPreconfiguration: boolean
) {
const mergedIsDefault = data.is_default ?? originalOutput.is_default;
- const fleetServerPolicies = await findPoliciesWithFleetServer(soClient, id, mergedIsDefault);
+ const { policiesWithFleetServer, policiesWithSynthetics } =
+ await findPoliciesWithFleetServerOrSynthetics(soClient, id, mergedIsDefault);
if (data.type === outputType.Logstash || originalOutput.type === outputType.Logstash) {
await validateLogstashOutputNotUsedInAPMPolicy(soClient, id, mergedIsDefault);
}
- // prevent changing an ES output to logstash or kafka if it's used by fleet server policies
+ // prevent changing an ES output to logstash or kafka if it's used by fleet server or synthetics policies
if (
originalOutput.type === outputType.Elasticsearch &&
(data?.type === outputType.Logstash || data?.type === outputType.Kafka)
) {
// Validate no policy with fleet server use that policy
- validateOutputNotUsedInFleetServerPolicy(fleetServerPolicies, data.type);
+ validateOutputNotUsedInPolicy(policiesWithFleetServer, data.type, 'Fleet Server');
+ validateOutputNotUsedInPolicy(policiesWithSynthetics, data.type, 'Synthetics');
}
- await updateFleetServerPoliciesDataOutputId(
+ await updateAgentPoliciesDataOutputId(
soClient,
esClient,
data,
mergedIsDefault,
defaultDataOutputId,
- fleetServerPolicies,
+ _.uniq([...policiesWithFleetServer, ...policiesWithSynthetics]),
fromPreconfiguration
);
}
-async function updateFleetServerPoliciesDataOutputId(
+async function updateAgentPoliciesDataOutputId(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
data: Nullable>,
isDefault: boolean,
defaultDataOutputId: string | null,
- fleetServerPolicies: AgentPolicy[],
+ agentPolicies: AgentPolicy[],
fromPreconfiguration: boolean
) {
// if a logstash output is updated to become default
// if fleet server policies don't have data_output_id
// update them to use the default output
if ((data?.type === outputType.Logstash || data?.type === outputType.Kafka) && isDefault) {
- for (const policy of fleetServerPolicies) {
+ for (const policy of agentPolicies) {
if (!policy.data_output_id) {
await agentPolicyService.update(
soClient,
@@ -415,14 +418,15 @@ class OutputService {
);
}
}
- const fleetServerPolicies = await findPoliciesWithFleetServer(soClient);
- await updateFleetServerPoliciesDataOutputId(
+ const { policiesWithFleetServer, policiesWithSynthetics } =
+ await findPoliciesWithFleetServerOrSynthetics(soClient);
+ await updateAgentPoliciesDataOutputId(
soClient,
esClient,
data,
data.is_default,
defaultDataOutputId,
- fleetServerPolicies,
+ _.uniq([...policiesWithFleetServer, ...policiesWithSynthetics]),
options?.fromPreconfiguration ?? false
);
diff --git a/x-pack/plugins/index_lifecycle_management/server/config.ts b/x-pack/plugins/index_lifecycle_management/server/config.ts
index 7fdec20bbb050..5a02e404ad2b7 100644
--- a/x-pack/plugins/index_lifecycle_management/server/config.ts
+++ b/x-pack/plugins/index_lifecycle_management/server/config.ts
@@ -28,7 +28,14 @@ const schemaLatest = schema.object(
* Disables the plugin.
* Added back in 8.8.
*/
- enabled: schema.boolean({ defaultValue: true }),
+ enabled: schema.conditional(
+ schema.contextRef('serverless'),
+ true,
+ // ILM is disabled in serverless; refer to the serverless.yml file as the source of truth
+ // We take this approach in order to have a central place (serverless.yml) to view disabled plugins across Kibana
+ schema.boolean({ defaultValue: true }),
+ schema.never()
+ ),
},
{ defaultValue: undefined }
);
diff --git a/x-pack/plugins/lens/common/content_management/v1/cm_services.ts b/x-pack/plugins/lens/common/content_management/v1/cm_services.ts
index c0e09f5041110..22e1af6272978 100644
--- a/x-pack/plugins/lens/common/content_management/v1/cm_services.ts
+++ b/x-pack/plugins/lens/common/content_management/v1/cm_services.ts
@@ -28,7 +28,7 @@ const referencesSchema = schema.arrayOf(referenceSchema);
const lensAttributesSchema = schema.object(
{
title: schema.string(),
- description: schema.maybe(schema.string()),
+ description: schema.maybe(schema.nullable(schema.string())),
visualizationType: schema.maybe(schema.string()),
state: schema.maybe(schema.any()),
uiStateJSON: schema.maybe(schema.string()),
diff --git a/x-pack/plugins/license_management/server/config.ts b/x-pack/plugins/license_management/server/config.ts
index 23449bc19e793..f413335cc23ef 100644
--- a/x-pack/plugins/license_management/server/config.ts
+++ b/x-pack/plugins/license_management/server/config.ts
@@ -26,7 +26,14 @@ const schemaLatest = schema.object(
* Disables the plugin.
* Added back in 8.8.
*/
- enabled: schema.boolean({ defaultValue: true }),
+ enabled: schema.conditional(
+ schema.contextRef('serverless'),
+ true,
+ // License Management is disabled in serverless; refer to the serverless.yml file as the source of truth
+ // We take this approach in order to have a central place (serverless.yml) to view disabled plugins across Kibana
+ schema.boolean({ defaultValue: true }),
+ schema.never()
+ ),
},
{ defaultValue: undefined }
);
diff --git a/x-pack/plugins/osquery/cypress/tasks/api_fixtures.ts b/x-pack/plugins/osquery/cypress/tasks/api_fixtures.ts
index a87869d693348..b125693e8b915 100644
--- a/x-pack/plugins/osquery/cypress/tasks/api_fixtures.ts
+++ b/x-pack/plugins/osquery/cypress/tasks/api_fixtures.ts
@@ -8,7 +8,7 @@
import type {
RuleCreateProps,
RuleResponse,
-} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema';
+} from '@kbn/security-solution-plugin/common/api/detection_engine';
import type { AgentPolicy } from '@kbn/fleet-plugin/common';
import type { Case } from '@kbn/cases-plugin/common';
import { API_VERSIONS } from '../../common/constants';
diff --git a/x-pack/plugins/remote_clusters/server/config.ts b/x-pack/plugins/remote_clusters/server/config.ts
index 4f6c56191cd89..12275985a3aa9 100644
--- a/x-pack/plugins/remote_clusters/server/config.ts
+++ b/x-pack/plugins/remote_clusters/server/config.ts
@@ -26,7 +26,14 @@ const schemaLatest = schema.object(
* Disables the plugin.
* Added back in 8.8.
*/
- enabled: schema.boolean({ defaultValue: true }),
+ enabled: schema.conditional(
+ schema.contextRef('serverless'),
+ true,
+ // Remote Clusters is disabled in serverless; refer to the serverless.yml file as the source of truth
+ // We take this approach in order to have a central place (serverless.yml) to view disabled plugins across Kibana
+ schema.boolean({ defaultValue: true }),
+ schema.never()
+ ),
},
{ defaultValue: undefined }
);
diff --git a/x-pack/plugins/rollup/server/config.ts b/x-pack/plugins/rollup/server/config.ts
index 953cd4b283f97..c0d5c1fbe92ee 100644
--- a/x-pack/plugins/rollup/server/config.ts
+++ b/x-pack/plugins/rollup/server/config.ts
@@ -26,7 +26,14 @@ const schemaLatest = schema.object(
* Disables the plugin.
* Added back in 8.8.
*/
- enabled: schema.boolean({ defaultValue: true }),
+ enabled: schema.conditional(
+ schema.contextRef('serverless'),
+ true,
+ // Rollups is disabled in serverless; refer to the serverless.yml file as the source of truth
+ // We take this approach in order to have a central place (serverless.yml) to view disabled plugins across Kibana
+ schema.boolean({ defaultValue: true }),
+ schema.never()
+ ),
},
{ defaultValue: undefined }
);
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/alert_tags/index.ts
similarity index 79%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/index.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/alert_tags/index.ts
index 76da687604028..7adc565a09c8e 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/index.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/alert_tags/index.ts
@@ -5,5 +5,4 @@
* 2.0.
*/
-export * from './error_schema';
-export * from './warning_schema';
+export * from './set_alert_tags/set_alert_tags_route';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/alert_tags/mocks.ts
similarity index 75%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/common/index.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/alert_tags/mocks.ts
index e129a72362ed7..985a74f34e669 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/index.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/alert_tags/mocks.ts
@@ -5,6 +5,4 @@
* 2.0.
*/
-export * from './pagination';
-export * from './schemas';
-export * from './sorting';
+export * from './set_alert_tags/set_alert_tags_route.mock';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_alert_tags_schema.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/alert_tags/set_alert_tags/set_alert_tags_route.mock.ts
similarity index 67%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_alert_tags_schema.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/alert_tags/set_alert_tags/set_alert_tags_route.mock.ts
index 4f3bf93550223..f1e05ad7f125a 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_alert_tags_schema.mock.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/alert_tags/set_alert_tags/set_alert_tags_route.mock.ts
@@ -5,10 +5,13 @@
* 2.0.
*/
-import type { SetAlertTagsSchema } from './set_alert_tags_schema';
+import type { SetAlertTagsRequestBody } from './set_alert_tags_route';
export const getSetAlertTagsRequestMock = (
tagsToAdd: string[] = [],
tagsToRemove: string[] = [],
ids: string[] = []
-): SetAlertTagsSchema => ({ tags: { tags_to_add: tagsToAdd, tags_to_remove: tagsToRemove }, ids });
+): SetAlertTagsRequestBody => ({
+ tags: { tags_to_add: tagsToAdd, tags_to_remove: tagsToRemove },
+ ids,
+});
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_alert_tags_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/alert_tags/set_alert_tags/set_alert_tags_route.ts
similarity index 57%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_alert_tags_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/alert_tags/set_alert_tags/set_alert_tags_route.ts
index cb11c8c70c8ab..8a6f93c20b770 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_alert_tags_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/alert_tags/set_alert_tags/set_alert_tags_route.ts
@@ -7,14 +7,14 @@
import * as t from 'io-ts';
-import { alert_tag_ids, alert_tags } from '../common/schemas';
+import { alert_tag_ids, alert_tags } from '../../model';
-export const setAlertTagsSchema = t.exact(
+export const setAlertTagsRequestBody = t.exact(
t.type({
tags: alert_tags,
ids: alert_tag_ids,
})
);
-export type SetAlertTagsSchema = t.TypeOf;
-export type SetAlertTagsSchemaDecoded = SetAlertTagsSchema;
+export type SetAlertTagsRequestBody = t.TypeOf;
+export type SetAlertTagsRequestBodyDecoded = SetAlertTagsRequestBody;
diff --git a/x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/api/get_installed_integrations/response_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/fleet_integrations/get_installed_integrations/get_installed_integrations_route.ts
similarity index 80%
rename from x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/api/get_installed_integrations/response_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/fleet_integrations/get_installed_integrations/get_installed_integrations_route.ts
index d970fb7061a44..4f3c4e6f942da 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/api/get_installed_integrations/response_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/fleet_integrations/get_installed_integrations/get_installed_integrations_route.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import type { InstalledIntegrationArray } from '../../model/installed_integrations';
+import type { InstalledIntegrationArray } from '../model/installed_integrations';
export interface GetInstalledIntegrationsResponse {
installed_integrations: InstalledIntegrationArray;
diff --git a/x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/fleet_integrations/index.ts
similarity index 74%
rename from x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/index.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/fleet_integrations/index.ts
index e79ebecbdb1cd..63a824a430c6e 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/index.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/fleet_integrations/index.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-export * from './api/get_installed_integrations/response_schema';
-export * from './api/urls';
+export * from './get_installed_integrations/get_installed_integrations_route';
+export * from './urls';
export * from './model/installed_integrations';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/model/installed_integrations.ts b/x-pack/plugins/security_solution/common/api/detection_engine/fleet_integrations/model/installed_integrations.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/model/installed_integrations.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/fleet_integrations/model/installed_integrations.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/api/urls.ts b/x-pack/plugins/security_solution/common/api/detection_engine/fleet_integrations/urls.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/api/urls.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/fleet_integrations/urls.ts
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/index.ts
new file mode 100644
index 0000000000000..093cc2d43bc33
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/index.ts
@@ -0,0 +1,16 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './alert_tags';
+export * from './fleet_integrations';
+export * from './model';
+export * from './prebuilt_rules';
+export * from './rule_exceptions';
+export * from './rule_management';
+export * from './rule_monitoring';
+export * from './signals';
+export * from './signals_migration';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/8.0.0/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.0.0/index.ts
similarity index 97%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/8.0.0/index.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.0.0/index.ts
index b347ffbd67ea5..3dd5d8362a497 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/8.0.0/index.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.0.0/index.ts
@@ -68,9 +68,9 @@ import type {
ALERT_RULE_TIMELINE_ID,
ALERT_RULE_TIMELINE_TITLE,
ALERT_RULE_TIMESTAMP_OVERRIDE,
-} from '../../../../field_maps/field_names';
+} from '../../../../../field_maps/field_names';
// TODO: Create and import 8.0.0 versioned RuleAlertAction type
-import type { RuleAlertAction, SearchTypes } from '../../../types';
+import type { RuleAlertAction, SearchTypes } from '../../../../../detection_engine/types';
/* DO NOT MODIFY THIS SCHEMA TO ADD NEW FIELDS. These types represent the alerts that shipped in 8.0.0.
Any changes to these types should be bug fixes so the types more accurately represent the alerts from 8.0.0.
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/8.4.0/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.4.0/index.ts
similarity index 98%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/8.4.0/index.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.4.0/index.ts
index 703e324a4fb24..b7136cf1213eb 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/8.4.0/index.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.4.0/index.ts
@@ -12,7 +12,7 @@ import type {
ALERT_GROUP_INDEX,
ALERT_NEW_TERMS,
ALERT_RULE_INDICES,
-} from '../../../../field_maps/field_names';
+} from '../../../../../field_maps/field_names';
import type {
Ancestor800,
BaseFields800,
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/8.6.0/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.6.0/index.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/8.6.0/index.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.6.0/index.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/8.7.0/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.7.0/index.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/8.7.0/index.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.7.0/index.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/8.8.0/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.8.0/index.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/8.8.0/index.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.8.0/index.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/8.9.0/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.9.0/index.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/8.9.0/index.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.9.0/index.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/README.md b/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/README.md
similarity index 89%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/README.md
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/README.md
index c7acf84813f08..481fb04e5d3f7 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/README.md
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/README.md
@@ -20,7 +20,7 @@ Static types are a powerful tool for ensuring code correctness. However, each de
The schemas in this directory have 2 primary purposes: (1) separate the alert document schemas from the FieldMaps, and (2) set up a code structure that enables easy versioning of alert schemas. During the Detection Engine migration to the rule registry we used the FieldMaps to define the alert schema, but ended up with numerous type casts and some bugs in the process. This common directory stores the various alert schemas by Kibana version.
-x-pack/plugins/security_solution/common/detection_engine/schemas/alerts initially contains index.ts and one folder, 8.0.0. index.ts imports the schemas from 8.0.0 and re-exports them as ...Latest, denoting that those are the "write" schemas. The reason for this is that as we add new schemas, there are many places server side where we want to ensure that we're writing the latest alert schema. By having index.ts re-export 8.0.0 schemas, when we add make a new alert schema in the future (e.g. adding an additional field in 8.x) we can simply update index.ts to re-export the new schema instead of the previous schema. index.ts also exports a DetectionAlert which is the "read" schema - this type will be maintained as a union of all versioned alert schemas, which is needed to accurately type alerts that are read from the alerts index.
+x-pack/plugins/security_solution/common/api/detection_engine/model/alerts initially contains index.ts and one folder, 8.0.0. index.ts imports the schemas from 8.0.0 and re-exports them as ...Latest, denoting that those are the "write" schemas. The reason for this is that as we add new schemas, there are many places server side where we want to ensure that we're writing the latest alert schema. By having index.ts re-export 8.0.0 schemas, when we add make a new alert schema in the future (e.g. adding an additional field in 8.x) we can simply update index.ts to re-export the new schema instead of the previous schema. index.ts also exports a DetectionAlert which is the "read" schema - this type will be maintained as a union of all versioned alert schemas, which is needed to accurately type alerts that are read from the alerts index.
## Reading vs writing alerts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/index.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/alerts/index.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/index.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.mocks.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/error_schema.mocks.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.mocks.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/error_schema.mocks.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/error_schema.test.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/error_schema.test.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/error_schema.ts
similarity index 89%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/error_schema.ts
index 2c1cf288afe03..e6f2fecbf7e16 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/error_schema.ts
@@ -8,8 +8,8 @@
import { NonEmptyString } from '@kbn/securitysolution-io-ts-types';
import * as t from 'io-ts';
-import { RuleSignatureId } from '../../rule_schema';
-import { status_code, message } from '../common/schemas';
+import { RuleSignatureId } from './rule_schema';
+import { status_code, message } from './schemas';
// We use id: t.string intentionally and _never_ the id from global schemas as
// sometimes echo back out the id that the user gave us and it is not guaranteed
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/model/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/index.ts
new file mode 100644
index 0000000000000..00d17d55817a5
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/index.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
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './alerts';
+export * from './rule_response_actions';
+export * from './rule_schema';
+export * from './error_schema';
+export * from './pagination';
+export * from './schemas';
+export * from './sorting';
+export * from './warning_schema';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/pagination.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/pagination.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/common/pagination.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/pagination.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_response_actions/schemas/endpoint.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/endpoint.ts
similarity index 93%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_response_actions/schemas/endpoint.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/endpoint.ts
index 27d68c4e816d0..0aa3f97509f80 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_response_actions/schemas/endpoint.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/endpoint.ts
@@ -6,7 +6,7 @@
*/
import * as t from 'io-ts';
-import { ENABLED_AUTOMATED_RESPONSE_ACTION_COMMANDS } from '../../../endpoint/service/response_actions/constants';
+import { ENABLED_AUTOMATED_RESPONSE_ACTION_COMMANDS } from '../../../../endpoint/service/response_actions/constants';
// to enable using RESPONSE_ACTION_API_COMMANDS_NAMES as a type
function keyObject(arr: T): { [K in T[number]]: null } {
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_response_actions/schemas/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/index.ts
similarity index 84%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_response_actions/schemas/index.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/index.ts
index 539ac438bf57f..6738515699814 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_response_actions/schemas/index.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/index.ts
@@ -6,3 +6,5 @@
*/
export * from './response_actions';
+export * from './endpoint';
+export * from './osquery';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_response_actions/schemas/osquery.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/osquery.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_response_actions/schemas/osquery.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/osquery.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_response_actions/schemas/response_actions.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/response_actions.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_response_actions/schemas/response_actions.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/response_actions.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/build_rule_schemas.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/build_rule_schemas.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/build_rule_schemas.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/build_rule_schemas.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/field_overrides.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes/field_overrides.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/field_overrides.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes/field_overrides.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/misc_attributes.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes/misc_attributes.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/misc_attributes.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes/misc_attributes.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/related_integrations.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes/related_integrations.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/related_integrations.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes/related_integrations.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/required_fields.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes/required_fields.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/required_fields.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes/required_fields.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/saved_objects.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes/saved_objects.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/saved_objects.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes/saved_objects.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/timeline_template.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes/timeline_template.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/timeline_template.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes/timeline_template.ts
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/index.ts
new file mode 100644
index 0000000000000..0c207b17a548b
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/index.ts
@@ -0,0 +1,21 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './common_attributes/field_overrides';
+export * from './common_attributes/misc_attributes';
+export * from './common_attributes/related_integrations';
+export * from './common_attributes/required_fields';
+export * from './common_attributes/saved_objects';
+export * from './common_attributes/timeline_template';
+
+export * from './specific_attributes/eql_attributes';
+export * from './specific_attributes/new_terms_attributes';
+export * from './specific_attributes/query_attributes';
+export * from './specific_attributes/threshold_attributes';
+
+export * from './rule_schemas';
+export * from './build_rule_schemas';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/mocks.ts
similarity index 73%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/index.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/mocks.ts
index 56ea598c58b0d..9ae3e0672efc5 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/index.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/mocks.ts
@@ -5,5 +5,5 @@
* 2.0.
*/
-export * from './query_signals_index_schema';
-export * from './set_signal_status_schema';
+export * from './rule_request_schema.mock';
+export * from './rule_response_schema.mock';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_request_schema.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_request_schema.mock.ts
similarity index 98%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_request_schema.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_request_schema.mock.ts
index d76450a0e0425..9ff3e50ea5877 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_request_schema.mock.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_request_schema.mock.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../constants';
+import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../../constants';
import type {
MachineLearningRuleCreateProps,
MachineLearningRuleUpdateProps,
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_request_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_request_schema.test.ts
similarity index 99%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_request_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_request_schema.test.ts
index dab249557cc5a..a49112a98f81d 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_request_schema.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_request_schema.test.ts
@@ -10,7 +10,7 @@ import { left } from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/pipeable';
import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils';
-import { getListArrayMock } from '../../schemas/types/lists.mock';
+import { getListArrayMock } from '../../../../detection_engine/schemas/types/lists.mock';
import type { SavedQueryRuleCreateProps } from './rule_schemas';
import { RuleCreateProps } from './rule_schemas';
import {
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_response_schema.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_response_schema.mock.ts
similarity index 97%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_response_schema.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_response_schema.mock.ts
index 7ccdd03b1355c..521e9918a6521 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_response_schema.mock.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_response_schema.mock.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../constants';
+import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../../constants';
import type {
EqlRule,
MachineLearningRule,
@@ -14,7 +14,7 @@ import type {
SharedResponseProps,
ThreatMatchRule,
} from './rule_schemas';
-import { getListArrayMock } from '../../schemas/types/lists.mock';
+import { getListArrayMock } from '../../../../detection_engine/schemas/types/lists.mock';
export const ANCHOR_DATE = '2020-02-20T03:57:54.037Z';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_response_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_response_schema.test.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_response_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_response_schema.test.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_schemas.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_schemas.ts
similarity index 99%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_schemas.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_schemas.ts
index ff4bb72a5eb65..93fd0aa8d0af8 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_schemas.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_schemas.ts
@@ -27,8 +27,8 @@ import {
threat_query,
} from '@kbn/securitysolution-io-ts-alerting-types';
-import { RuleExecutionSummary } from '../../rule_monitoring';
-import { ResponseActionArray } from '../../rule_response_actions/schemas';
+import { RuleExecutionSummary } from '../../rule_monitoring/model';
+import { ResponseActionArray } from '../rule_response_actions';
import {
saved_id,
anomaly_threshold,
@@ -37,7 +37,7 @@ import {
created_at,
created_by,
revision,
-} from '../../schemas/common';
+} from '../schemas';
import {
AlertsIndex,
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/eql_attributes.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/eql_attributes.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/eql_attributes.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/eql_attributes.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/new_terms_attributes.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/new_terms_attributes.ts
similarity index 92%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/new_terms_attributes.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/new_terms_attributes.ts
index 6d9f39011b675..fa3e8e5860116 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/new_terms_attributes.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/new_terms_attributes.ts
@@ -7,7 +7,7 @@
import * as t from 'io-ts';
import { LimitedSizeArray, NonEmptyString } from '@kbn/securitysolution-io-ts-types';
-import { MAX_NUMBER_OF_NEW_TERMS_FIELDS } from '../../../../constants';
+import { MAX_NUMBER_OF_NEW_TERMS_FIELDS } from '../../../../../constants';
// Attributes specific to New Terms rules
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/query_attributes.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/query_attributes.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/query_attributes.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/query_attributes.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/threshold_attributes.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/threshold_attributes.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/threshold_attributes.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/threshold_attributes.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/schemas.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/schemas.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/sorting.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/sorting.test.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/common/sorting.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/sorting.test.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/sorting.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/sorting.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/common/sorting.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/sorting.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/warning_schema/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/warning_schema.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/warning_schema/index.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/model/warning_schema.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/response_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.test.ts
similarity index 98%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/response_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.test.ts
index e721e6f41cc19..83c09d2dcab26 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/response_schema.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.test.ts
@@ -9,7 +9,7 @@ import { left } from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/pipeable';
import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils';
-import { GetPrebuiltRulesAndTimelinesStatusResponse } from './response_schema';
+import { GetPrebuiltRulesAndTimelinesStatusResponse } from './get_prebuilt_rules_and_timelines_status_route';
describe('Get prebuilt rules and timelines status response schema', () => {
test('it should validate an empty prepackaged response with defaults', () => {
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/response_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/response_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/get_prebuilt_rules_status/response_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/get_prebuilt_rules_status/get_prebuilt_rules_status_route.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/get_prebuilt_rules_status/response_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/get_prebuilt_rules_status/get_prebuilt_rules_status_route.ts
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/index.ts
new file mode 100644
index 0000000000000..38607fbd30513
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/index.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route';
+export * from './get_prebuilt_rules_status/get_prebuilt_rules_status_route';
+export * from './install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route';
+export * from './perform_rule_installation/perform_rule_installation_route';
+export * from './perform_rule_upgrade/perform_rule_upgrade_route';
+export * from './review_rule_installation/review_rule_installation_route';
+export * from './review_rule_upgrade/review_rule_upgrade_route';
+export * from './urls';
+export * from './model/aggregated_prebuilt_rules_error';
+export * from './model/diff/diffable_rule/build_schema';
+export * from './model/diff/diffable_rule/diffable_field_types';
+export * from './model/diff/diffable_rule/diffable_rule';
+export * from './model/diff/rule_diff/fields_diff';
+export * from './model/diff/rule_diff/rule_diff';
+export * from './model/diff/three_way_diff/three_way_diff_outcome';
+export * from './model/diff/three_way_diff/three_way_diff';
+export * from './model/diff/three_way_diff/three_way_merge_outcome';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/response_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.test.ts
similarity index 97%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/response_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.test.ts
index 6833a5891a2c2..7f049af0d78b8 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/response_schema.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.test.ts
@@ -9,7 +9,7 @@ import { left } from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/pipeable';
import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils';
-import { InstallPrebuiltRulesAndTimelinesResponse } from './response_schema';
+import { InstallPrebuiltRulesAndTimelinesResponse } from './install_prebuilt_rules_and_timelines_route';
describe('Install prebuilt rules and timelines response schema', () => {
test('it should validate an empty prepackaged response with defaults', () => {
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/response_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/response_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rules/aggregated_prebuilt_rules_error.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/aggregated_prebuilt_rules_error.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rules/aggregated_prebuilt_rules_error.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/aggregated_prebuilt_rules_error.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/diffable_rule/build_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/diffable_rule/build_schema.ts
similarity index 89%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/diffable_rule/build_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/diffable_rule/build_schema.ts
index b0b60f70d1e63..b57882ffdfc5c 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/diffable_rule/build_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/diffable_rule/build_schema.ts
@@ -6,7 +6,7 @@
*/
import * as t from 'io-ts';
-import { orUndefined } from '../../../../rule_schema/model/build_rule_schemas';
+import { orUndefined } from '../../../../model';
interface RuleFields {
required: TRequired;
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_field_types.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_field_types.ts
similarity index 97%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_field_types.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_field_types.ts
index 3e07566afbf96..e2f0480d092aa 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_field_types.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_field_types.ts
@@ -19,8 +19,8 @@ import {
TimelineTemplateTitle,
TimestampOverride as TimestampOverrideFieldName,
TimestampOverrideFallbackDisabled,
-} from '../../../../rule_schema';
-import { saved_id } from '../../../../schemas/common';
+ saved_id,
+} from '../../../../model';
// -------------------------------------------------------------------------------------------------
// Rule data source
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_rule.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_rule.ts
similarity index 98%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_rule.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_rule.ts
index 8ce2fb9bf7f1a..6dad2ff0cf6df 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_rule.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_rule.ts
@@ -47,9 +47,8 @@ import {
Threshold,
TiebreakerField,
TimestampField,
-} from '../../../../rule_schema';
-
-import { anomaly_threshold } from '../../../../schemas/common';
+ anomaly_threshold,
+} from '../../../../model';
import {
BuildingBlockObject,
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/rule_diff/fields_diff.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/rule_diff/fields_diff.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/rule_diff/fields_diff.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/rule_diff/fields_diff.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/rule_diff/rule_diff.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/rule_diff/rule_diff.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/rule_diff/rule_diff.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/rule_diff/rule_diff.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff_outcome.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff_outcome.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff_outcome.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff_outcome.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_merge_outcome.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_merge_outcome.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_merge_outcome.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_merge_outcome.ts
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/index.ts
new file mode 100644
index 0000000000000..7e550633d8efc
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/index.ts
@@ -0,0 +1,16 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './aggregated_prebuilt_rules_error';
+export * from './diff/diffable_rule/build_schema';
+export * from './diff/diffable_rule/diffable_field_types';
+export * from './diff/diffable_rule/diffable_rule';
+export * from './diff/rule_diff/fields_diff';
+export * from './diff/rule_diff/rule_diff';
+export * from './diff/three_way_diff/three_way_diff_outcome';
+export * from './diff/three_way_diff/three_way_diff';
+export * from './diff/three_way_diff/three_way_merge_outcome';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/perform_rule_installation/perform_rule_installation_request_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_installation/perform_rule_installation_route.ts
similarity index 66%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/perform_rule_installation/perform_rule_installation_request_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_installation/perform_rule_installation_route.ts
index 3dc0c3619b2ee..fca8ce25d3ba1 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/perform_rule_installation/perform_rule_installation_request_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_installation/perform_rule_installation_route.ts
@@ -5,6 +5,8 @@
* 2.0.
*/
import * as t from 'io-ts';
+import type { RuleResponse } from '../../model';
+import type { AggregatedPrebuiltRuleError } from '../model';
export const RuleVersionSpecifier = t.exact(
t.type({
@@ -39,3 +41,26 @@ export const PerformRuleInstallationRequestBody = t.union([
export type PerformRuleInstallationRequestBody = t.TypeOf<
typeof PerformRuleInstallationRequestBody
>;
+
+export enum SkipRuleInstallReason {
+ ALREADY_INSTALLED = 'ALREADY_INSTALLED',
+}
+
+export interface SkippedRuleInstall {
+ rule_id: string;
+ reason: SkipRuleInstallReason;
+}
+
+export interface PerformRuleInstallationResponseBody {
+ summary: {
+ total: number;
+ succeeded: number;
+ skipped: number;
+ failed: number;
+ };
+ results: {
+ created: RuleResponse[];
+ skipped: SkippedRuleInstall[];
+ };
+ errors: AggregatedPrebuiltRuleError[];
+}
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/perform_rule_upgrade/perform_rule_upgrade_request_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.ts
similarity index 79%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/perform_rule_upgrade/perform_rule_upgrade_request_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.ts
index eb92782f4d916..b1d3b166a513e 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/perform_rule_upgrade/perform_rule_upgrade_request_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.ts
@@ -8,6 +8,9 @@
import { enumeration } from '@kbn/securitysolution-io-ts-types';
import * as t from 'io-ts';
+import type { RuleResponse } from '../../model';
+import type { AggregatedPrebuiltRuleError } from '../model';
+
export enum PickVersionValues {
BASE = 'BASE',
CURRENT = 'CURRENT',
@@ -70,3 +73,26 @@ export const PerformRuleUpgradeRequestBody = t.union([
UpgradeSpecificRulesRequest,
]);
export type PerformRuleUpgradeRequestBody = t.TypeOf;
+
+export enum SkipRuleUpgradeReason {
+ RULE_UP_TO_DATE = 'RULE_UP_TO_DATE',
+}
+
+export interface SkippedRuleUpgrade {
+ rule_id: string;
+ reason: SkipRuleUpgradeReason;
+}
+
+export interface PerformRuleUpgradeResponseBody {
+ summary: {
+ total: number;
+ succeeded: number;
+ skipped: number;
+ failed: number;
+ };
+ results: {
+ updated: RuleResponse[];
+ skipped: SkippedRuleUpgrade[];
+ };
+ errors: AggregatedPrebuiltRuleError[];
+}
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/review_rule_installation/response_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/review_rule_installation/review_rule_installation_route.ts
similarity index 90%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/review_rule_installation/response_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/review_rule_installation/review_rule_installation_route.ts
index 49757b80630a7..7a7f4878defb3 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/review_rule_installation/response_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/review_rule_installation/review_rule_installation_route.ts
@@ -5,8 +5,8 @@
* 2.0.
*/
-import type { RuleSignatureId, RuleTagArray, RuleVersion } from '../../../rule_schema';
-import type { DiffableRule } from '../../model/diff/diffable_rule/diffable_rule';
+import type { RuleSignatureId, RuleTagArray, RuleVersion } from '../../model';
+import type { DiffableRule } from '../model';
export interface ReviewRuleInstallationResponseBody {
/** Aggregated info about all rules available for installation */
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/review_rule_upgrade/response_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/review_rule_upgrade/review_rule_upgrade_route.ts
similarity index 84%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/review_rule_upgrade/response_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/review_rule_upgrade/review_rule_upgrade_route.ts
index 52e12bc49fac6..99249cfab1cbc 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/review_rule_upgrade/response_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/review_rule_upgrade/review_rule_upgrade_route.ts
@@ -5,9 +5,8 @@
* 2.0.
*/
-import type { RuleObjectId, RuleSignatureId, RuleTagArray } from '../../../rule_schema';
-import type { DiffableRule } from '../../model/diff/diffable_rule/diffable_rule';
-import type { PartialRuleDiff } from '../../model/diff/rule_diff/rule_diff';
+import type { RuleObjectId, RuleSignatureId, RuleTagArray } from '../../model';
+import type { DiffableRule, PartialRuleDiff } from '../model';
export interface ReviewRuleUpgradeResponseBody {
/** Aggregated info about all rules available for upgrade */
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/urls.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/urls.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/urls.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/urls.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/create_rule_exceptions/request_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/create_rule_exceptions/create_rule_exceptions_route.test.ts
similarity index 99%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/create_rule_exceptions/request_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/create_rule_exceptions/create_rule_exceptions_route.test.ts
index 93b4e9f128a7b..b05cc35ce75fa 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/create_rule_exceptions/request_schema.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/create_rule_exceptions/create_rule_exceptions_route.test.ts
@@ -13,7 +13,7 @@ import { getCreateExceptionListItemSchemaMock } from '@kbn/lists-plugin/common/s
import {
CreateRuleExceptionsRequestBody,
CreateRuleExceptionsRequestParams,
-} from './request_schema';
+} from './create_rule_exceptions_route';
describe('CreateRuleExceptionsRequestParams', () => {
test('empty objects do not validate', () => {
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/create_rule_exceptions/request_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/create_rule_exceptions/create_rule_exceptions_route.ts
similarity index 83%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/create_rule_exceptions/request_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/create_rule_exceptions/create_rule_exceptions_route.ts
index 57ef1f8974708..42ef5482b5b5a 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/create_rule_exceptions/request_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/create_rule_exceptions/create_rule_exceptions_route.ts
@@ -7,10 +7,13 @@
import * as t from 'io-ts';
-import type { CreateRuleExceptionListItemSchemaDecoded } from '@kbn/securitysolution-io-ts-list-types';
+import type {
+ CreateRuleExceptionListItemSchemaDecoded,
+ ExceptionListItemSchema,
+} from '@kbn/securitysolution-io-ts-list-types';
import { createRuleExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types';
-import { RuleObjectId } from '../../../rule_schema';
+import { RuleObjectId } from '../../model';
/**
* URL path parameters of the API route.
@@ -43,3 +46,5 @@ export type CreateRuleExceptionsRequestBodyDecoded = Omit<
> & {
items: CreateRuleExceptionListItemSchemaDecoded[];
};
+
+export type CreateRuleExceptionsResponse = ExceptionListItemSchema[];
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/find_exception_references/find_exception_references_route.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/find_exception_references/find_exception_references_route.test.ts
new file mode 100644
index 0000000000000..003060f4421aa
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/find_exception_references/find_exception_references_route.test.ts
@@ -0,0 +1,247 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { exactCheck, formatErrors, foldLeftRight } from '@kbn/securitysolution-io-ts-utils';
+import { getExceptionListSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_schema.mock';
+import {
+ exceptionListRuleReferencesSchema,
+ rulesReferencedByExceptionListsSchema,
+ findExceptionReferencesOnRuleSchema,
+} from './find_exception_references_route';
+import type {
+ ExceptionListRuleReferencesSchema,
+ RulesReferencedByExceptionListsSchema,
+ FindExceptionReferencesOnRuleSchema,
+} from './find_exception_references_route';
+
+describe('Find exception list references', () => {
+ describe('request schema', () => {
+ test('validates all fields', () => {
+ const payload: FindExceptionReferencesOnRuleSchema = {
+ ids: 'abc,def',
+ list_ids: '123,456',
+ namespace_types: 'single,agnostic',
+ };
+
+ const decoded = findExceptionReferencesOnRuleSchema.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const output = foldLeftRight(checked);
+ expect(formatErrors(output.errors)).toEqual([]);
+ expect(output.schema).toEqual({
+ ids: ['abc', 'def'],
+ list_ids: ['123', '456'],
+ namespace_types: ['single', 'agnostic'],
+ });
+ });
+
+ test('"ids" can be optional', () => {
+ const payload: Omit = {
+ list_ids: '123,456',
+ namespace_types: 'single,agnostic',
+ };
+
+ const decoded = findExceptionReferencesOnRuleSchema.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const output = foldLeftRight(checked);
+ expect(formatErrors(output.errors)).toEqual([]);
+ expect(output.schema).toEqual({
+ list_ids: ['123', '456'],
+ namespace_types: ['single', 'agnostic'],
+ });
+ });
+
+ test('"list_ids" can be undefined', () => {
+ const payload: Omit = {
+ ids: 'abc',
+ namespace_types: 'single',
+ };
+
+ const decoded = findExceptionReferencesOnRuleSchema.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const output = foldLeftRight(checked);
+ expect(formatErrors(output.errors)).toEqual([]);
+ expect(output.schema).toEqual({
+ ids: ['abc'],
+ namespace_types: ['single'],
+ });
+ });
+
+ test('defaults "namespacetypes" to ["single"] if none set', () => {
+ const payload: Omit = {
+ ids: 'abc',
+ list_ids: '123',
+ };
+
+ const decoded = findExceptionReferencesOnRuleSchema.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const output = foldLeftRight(checked);
+ expect(formatErrors(output.errors)).toEqual([]);
+ expect(output.schema).toEqual({
+ ids: ['abc'],
+ list_ids: ['123'],
+ namespace_types: ['single'],
+ });
+ });
+
+ test('cannot add extra values', () => {
+ const payload: FindExceptionReferencesOnRuleSchema & { extra_value?: string } = {
+ ids: 'abc,def',
+ list_ids: '123,456',
+ namespace_types: 'single,agnostic',
+ extra_value: 'aaa',
+ };
+
+ const decoded = findExceptionReferencesOnRuleSchema.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const output = foldLeftRight(checked);
+ expect(formatErrors(output.errors)).toEqual(['invalid keys "extra_value"']);
+ expect(output.schema).toEqual({});
+ });
+ });
+
+ describe('response schema', () => {
+ describe('exceptionListRuleReferencesSchema', () => {
+ test('validates all fields', () => {
+ const payload: ExceptionListRuleReferencesSchema = {
+ ...getExceptionListSchemaMock(),
+ referenced_rules: [
+ {
+ name: 'My rule',
+ id: '4656dc92-5832-11ea-8e2d-0242ac130003',
+ rule_id: 'my-rule-id',
+ exception_lists: [
+ {
+ id: 'myListId',
+ list_id: 'my-list-id',
+ namespace_type: 'single',
+ type: 'detection',
+ },
+ ],
+ },
+ ],
+ };
+
+ const decoded = exceptionListRuleReferencesSchema.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const output = foldLeftRight(checked);
+ expect(formatErrors(output.errors)).toEqual([]);
+ expect(output.schema).toEqual(payload);
+ });
+
+ test('cannot add extra values', () => {
+ const payload: ExceptionListRuleReferencesSchema & { extra_value?: string } = {
+ extra_value: 'foo',
+ ...getExceptionListSchemaMock(),
+ referenced_rules: [
+ {
+ name: 'My rule',
+ id: '4656dc92-5832-11ea-8e2d-0242ac130003',
+ rule_id: 'my-rule-id',
+ exception_lists: [
+ {
+ id: 'myListId',
+ list_id: 'my-list-id',
+ namespace_type: 'single',
+ type: 'detection',
+ },
+ ],
+ },
+ ],
+ };
+
+ const decoded = exceptionListRuleReferencesSchema.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const output = foldLeftRight(checked);
+ expect(formatErrors(output.errors)).toEqual(['invalid keys "extra_value"']);
+ expect(output.schema).toEqual({});
+ });
+ });
+
+ describe('rulesReferencedByExceptionListsSchema', () => {
+ test('validates all fields', () => {
+ const payload: RulesReferencedByExceptionListsSchema = {
+ references: [
+ {
+ 'my-list-id': {
+ ...getExceptionListSchemaMock(),
+ referenced_rules: [
+ {
+ name: 'My rule',
+ id: '4656dc92-5832-11ea-8e2d-0242ac130003',
+ rule_id: 'my-rule-id',
+ exception_lists: [
+ {
+ id: 'myListId',
+ list_id: 'my-list-id',
+ namespace_type: 'single',
+ type: 'detection',
+ },
+ ],
+ },
+ ],
+ },
+ },
+ ],
+ };
+
+ const decoded = rulesReferencedByExceptionListsSchema.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const output = foldLeftRight(checked);
+ expect(formatErrors(output.errors)).toEqual([]);
+ expect(output.schema).toEqual(payload);
+ });
+
+ test('validates "references" with empty array', () => {
+ const payload: RulesReferencedByExceptionListsSchema = {
+ references: [],
+ };
+
+ const decoded = rulesReferencedByExceptionListsSchema.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const output = foldLeftRight(checked);
+ expect(formatErrors(output.errors)).toEqual([]);
+ expect(output.schema).toEqual({
+ references: [],
+ });
+ });
+
+ test('cannot add extra values', () => {
+ const payload: RulesReferencedByExceptionListsSchema & { extra_value?: string } = {
+ extra_value: 'foo',
+ references: [
+ {
+ 'my-list-id': {
+ ...getExceptionListSchemaMock(),
+ referenced_rules: [
+ {
+ name: 'My rule',
+ id: '4656dc92-5832-11ea-8e2d-0242ac130003',
+ rule_id: 'my-rule-id',
+ exception_lists: [
+ {
+ id: 'myListId',
+ list_id: 'my-list-id',
+ namespace_type: 'single',
+ type: 'detection',
+ },
+ ],
+ },
+ ],
+ },
+ },
+ ],
+ };
+
+ const decoded = rulesReferencedByExceptionListsSchema.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const output = foldLeftRight(checked);
+ expect(formatErrors(output.errors)).toEqual(['invalid keys "extra_value"']);
+ expect(output.schema).toEqual({});
+ });
+ });
+ });
+});
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/find_exception_references/response_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/find_exception_references/find_exception_references_route.ts
similarity index 60%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/find_exception_references/response_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/find_exception_references/find_exception_references_route.ts
index 32589e2d165ea..e495ab9647725 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/find_exception_references/response_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/find_exception_references/find_exception_references_route.ts
@@ -6,8 +6,38 @@
*/
import * as t from 'io-ts';
-import { exceptionListSchema, listArray, list_id } from '@kbn/securitysolution-io-ts-list-types';
-import { RuleName, RuleObjectId, RuleSignatureId } from '../../../rule_schema';
+import {
+ exceptionListSchema,
+ listArray,
+ list_id,
+ DefaultNamespaceArray,
+} from '@kbn/securitysolution-io-ts-list-types';
+import { NonEmptyStringArray } from '@kbn/securitysolution-io-ts-types';
+import { RuleName, RuleObjectId, RuleSignatureId } from '../../model';
+
+// If ids and list_ids are undefined, route will fetch all lists matching the
+// specified namespace type
+export const findExceptionReferencesOnRuleSchema = t.intersection([
+ t.exact(
+ t.type({
+ namespace_types: DefaultNamespaceArray,
+ })
+ ),
+ t.exact(
+ t.partial({
+ ids: NonEmptyStringArray,
+ list_ids: NonEmptyStringArray,
+ })
+ ),
+]);
+
+export type FindExceptionReferencesOnRuleSchema = t.OutputOf<
+ typeof findExceptionReferencesOnRuleSchema
+>;
+
+export type FindExceptionReferencesOnRuleSchemaDecoded = t.TypeOf<
+ typeof findExceptionReferencesOnRuleSchema
+>;
export const ruleReferenceRuleInfoSchema = t.exact(
t.type({
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/index.ts
new file mode 100644
index 0000000000000..0b5ccc3b3a648
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/index.ts
@@ -0,0 +1,10 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './create_rule_exceptions/create_rule_exceptions_route';
+export * from './find_exception_references/find_exception_references_route';
+export * from './urls';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/urls.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/urls.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/urls.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_exceptions/urls.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.mock.ts
similarity index 81%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.mock.ts
index fd210ad99680f..66ce78ff9b615 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.mock.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.mock.ts
@@ -5,8 +5,8 @@
* 2.0.
*/
-import { BulkActionType, BulkActionEditType } from './request_schema';
-import type { PerformBulkActionRequestBody } from './request_schema';
+import { BulkActionType, BulkActionEditType } from './bulk_actions_route';
+import type { PerformBulkActionRequestBody } from './bulk_actions_route';
export const getPerformBulkActionSchemaMock = (): PerformBulkActionRequestBody => ({
query: '',
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.test.ts
similarity index 99%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.test.ts
index 712312c50140d..70ae548674332 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.test.ts
@@ -7,7 +7,11 @@
import { left } from 'fp-ts/lib/Either';
import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils';
-import { PerformBulkActionRequestBody, BulkActionType, BulkActionEditType } from './request_schema';
+import {
+ PerformBulkActionRequestBody,
+ BulkActionType,
+ BulkActionEditType,
+} from './bulk_actions_route';
const retrieveValidationMessage = (payload: unknown) => {
const decoded = PerformBulkActionRequestBody.decode(payload);
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.ts
similarity index 83%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.ts
index 118c886e94042..c87b9e9a088ba 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.ts
@@ -16,13 +16,17 @@ import {
RuleActionParams,
} from '@kbn/securitysolution-io-ts-alerting-types';
+import type { BulkActionSkipResult } from '@kbn/alerting-plugin/common';
+import type { RuleResponse } from '../../model';
+import type { BulkActionsDryRunErrCode } from '../../../../constants';
+
import {
IndexPatternArray,
RuleQuery,
RuleTagArray,
TimelineTemplateId,
TimelineTemplateTitle,
-} from '../../../../rule_schema';
+} from '../../model';
export enum BulkActionType {
'enable' = 'enable',
@@ -218,3 +222,46 @@ export const PerformBulkActionRequestQuery = t.exact(
dry_run: t.union([t.literal('true'), t.literal('false')]),
})
);
+
+export interface RuleDetailsInError {
+ id: string;
+ name?: string;
+}
+export interface NormalizedRuleError {
+ message: string;
+ status_code: number;
+ err_code?: BulkActionsDryRunErrCode;
+ rules: RuleDetailsInError[];
+}
+export interface BulkEditActionResults {
+ updated: RuleResponse[];
+ created: RuleResponse[];
+ deleted: RuleResponse[];
+ skipped: BulkActionSkipResult[];
+}
+
+export interface BulkEditActionSummary {
+ failed: number;
+ skipped: number;
+ succeeded: number;
+ total: number;
+}
+export interface BulkEditActionSuccessResponse {
+ success: boolean;
+ rules_count: number;
+ attributes: {
+ results: BulkEditActionResults;
+ summary: BulkEditActionSummary;
+ };
+}
+export interface BulkEditActionErrorResponse {
+ status_code: number;
+ message: string;
+ attributes: {
+ results: BulkEditActionResults;
+ summary: BulkEditActionSummary;
+ errors?: NormalizedRuleError[];
+ };
+}
+
+export type BulkEditActionResponse = BulkEditActionSuccessResponse | BulkEditActionErrorResponse;
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_create_rules/request_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_create_rules/bulk_create_rules_route.test.ts
similarity index 98%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_create_rules/request_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_create_rules/bulk_create_rules_route.test.ts
index d2c297d401edb..bf06b41aef39b 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_create_rules/request_schema.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_create_rules/bulk_create_rules_route.test.ts
@@ -5,9 +5,9 @@
* 2.0.
*/
-import { BulkCreateRulesRequestBody } from './request_schema';
+import { BulkCreateRulesRequestBody } from './bulk_create_rules_route';
import { exactCheck, foldLeftRight, formatErrors } from '@kbn/securitysolution-io-ts-utils';
-import { getCreateRulesSchemaMock } from '../../../../../rule_schema/mocks';
+import { getCreateRulesSchemaMock } from '../../../model/rule_schema/mocks';
// only the basics of testing are here.
// see: rule_schemas.test.ts for the bulk of the validation tests
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_create_rules/request_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_create_rules/bulk_create_rules_route.ts
similarity index 88%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_create_rules/request_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_create_rules/bulk_create_rules_route.ts
index 846da78b4cbba..18f16cfdd3ce2 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_create_rules/request_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_create_rules/bulk_create_rules_route.ts
@@ -6,7 +6,7 @@
*/
import * as t from 'io-ts';
-import { RuleCreateProps } from '../../../../../rule_schema';
+import { RuleCreateProps } from '../../../model';
/**
* Request body parameters of the API route.
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_delete_rules/request_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_delete_rules/bulk_delete_rules_route.test.ts
similarity index 98%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_delete_rules/request_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_delete_rules/bulk_delete_rules_route.test.ts
index 6a709db317109..cdb4085eea1eb 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_delete_rules/request_schema.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_delete_rules/bulk_delete_rules_route.test.ts
@@ -6,7 +6,7 @@
*/
import { exactCheck, formatErrors, foldLeftRight } from '@kbn/securitysolution-io-ts-utils';
-import { BulkDeleteRulesRequestBody } from './request_schema';
+import { BulkDeleteRulesRequestBody } from './bulk_delete_rules_route';
// only the basics of testing are here.
// see: query_rules_schema.test.ts for the bulk of the validation tests
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_delete_rules/request_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_delete_rules/bulk_delete_rules_route.ts
similarity index 87%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_delete_rules/request_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_delete_rules/bulk_delete_rules_route.ts
index e290b57b4c404..0da4acf82f546 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_delete_rules/request_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_delete_rules/bulk_delete_rules_route.ts
@@ -6,7 +6,7 @@
*/
import * as t from 'io-ts';
-import { QueryRuleByIds } from '../../crud/read_rule/query_rule_by_ids';
+import { QueryRuleByIds } from '../../model/query_rule_by_ids';
/**
* Request body parameters of the API route.
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_patch_rules/request_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_patch_rules/bulk_patch_rules_route.test.ts
similarity index 97%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_patch_rules/request_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_patch_rules/bulk_patch_rules_route.test.ts
index 3d466d7d23894..9e1351c7f25f0 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_patch_rules/request_schema.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_patch_rules/bulk_patch_rules_route.test.ts
@@ -6,8 +6,8 @@
*/
import { exactCheck, formatErrors, foldLeftRight } from '@kbn/securitysolution-io-ts-utils';
-import type { PatchRuleRequestBody } from '../../crud/patch_rule/request_schema';
-import { BulkPatchRulesRequestBody } from './request_schema';
+import type { PatchRuleRequestBody } from '../../crud/patch_rule/patch_rule_route';
+import { BulkPatchRulesRequestBody } from './bulk_patch_rules_route';
// only the basics of testing are here.
// see: patch_rules_schema.test.ts for the bulk of the validation tests
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_patch_rules/request_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_patch_rules/bulk_patch_rules_route.ts
similarity index 86%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_patch_rules/request_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_patch_rules/bulk_patch_rules_route.ts
index 2dcd0c2a22d4b..ee8e4be710084 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_patch_rules/request_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_patch_rules/bulk_patch_rules_route.ts
@@ -6,7 +6,7 @@
*/
import * as t from 'io-ts';
-import { PatchRuleRequestBody } from '../../crud/patch_rule/request_schema';
+import { PatchRuleRequestBody } from '../../crud/patch_rule/patch_rule_route';
/**
* Request body parameters of the API route.
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_update_rules/request_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_update_rules/bulk_update_rules_route.test.ts
similarity index 98%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_update_rules/request_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_update_rules/bulk_update_rules_route.test.ts
index f2b3437273d01..46dbbd22b7aaa 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_update_rules/request_schema.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_update_rules/bulk_update_rules_route.test.ts
@@ -6,9 +6,9 @@
*/
import { exactCheck, formatErrors, foldLeftRight } from '@kbn/securitysolution-io-ts-utils';
-import type { RuleUpdateProps } from '../../../../../rule_schema';
-import { getUpdateRulesSchemaMock } from '../../../../../rule_schema/mocks';
-import { BulkUpdateRulesRequestBody } from './request_schema';
+import type { RuleUpdateProps } from '../../../model';
+import { getUpdateRulesSchemaMock } from '../../../model/rule_schema/mocks';
+import { BulkUpdateRulesRequestBody } from './bulk_update_rules_route';
// only the basics of testing are here.
// see: update_rules_schema.test.ts for the bulk of the validation tests
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_update_rules/request_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_update_rules/bulk_update_rules_route.ts
similarity index 88%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_update_rules/request_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_update_rules/bulk_update_rules_route.ts
index 5409e7b2bda43..649898adc9e37 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_update_rules/request_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/bulk_update_rules/bulk_update_rules_route.ts
@@ -6,7 +6,7 @@
*/
import * as t from 'io-ts';
-import { RuleUpdateProps } from '../../../../../rule_schema';
+import { RuleUpdateProps } from '../../../model';
/**
* Request body parameters of the API route.
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/response_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/response_schema.test.ts
similarity index 95%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/response_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/response_schema.test.ts
index 044af119f99ec..a149d73d333d4 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/response_schema.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/response_schema.test.ts
@@ -9,10 +9,9 @@ import { left } from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/pipeable';
import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils';
-import type { RuleResponse } from '../../../../rule_schema';
-import { getRulesSchemaMock } from '../../../../rule_schema/mocks';
-import type { ErrorSchema } from '../../../../schemas/response/error_schema';
-import { getErrorSchemaMock } from '../../../../schemas/response/error_schema.mocks';
+import type { RuleResponse, ErrorSchema } from '../../model';
+import { getRulesSchemaMock } from '../../model/rule_schema/mocks';
+import { getErrorSchemaMock } from '../../model/error_schema.mocks';
import { BulkCrudRulesResponse } from './response_schema';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/response_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/response_schema.ts
similarity index 77%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/response_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/response_schema.ts
index 9a0144e2cf758..b6f9bb359344b 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/response_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/bulk_crud/response_schema.ts
@@ -7,8 +7,7 @@
import * as t from 'io-ts';
-import { RuleResponse } from '../../../../rule_schema';
-import { errorSchema } from '../../../../schemas/response/error_schema';
+import { RuleResponse, errorSchema } from '../../model';
export type BulkCrudRulesResponse = t.TypeOf;
export const BulkCrudRulesResponse = t.array(t.union([RuleResponse, errorSchema]));
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/coverage_overview/request_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/coverage_overview/coverage_overview_route.ts
similarity index 76%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/coverage_overview/request_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/coverage_overview/coverage_overview_route.ts
index 48c3e4679702a..0f85a1fdc609a 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/coverage_overview/request_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/coverage_overview/coverage_overview_route.ts
@@ -79,3 +79,27 @@ export const CoverageOverviewRequestBody = t.exact(
filter: CoverageOverviewFilter,
})
);
+
+export type CoverageOverviewRuleAttributes = t.TypeOf;
+export const CoverageOverviewRuleAttributes = t.type({
+ name: t.string,
+ activity: CoverageOverviewRuleActivitySchema,
+});
+
+export type CoverageOverviewResponse = t.TypeOf;
+export const CoverageOverviewResponse = t.exact(
+ t.type({
+ /**
+ * Map having (tacticId, techniqueId or subtechniqueId) as the key and an array of rule ids as the value
+ */
+ coverage: t.record(t.string, NonEmptyArray(t.string)),
+ /**
+ * Array of unmapped rule ids
+ */
+ unmapped_rule_ids: t.array(t.string),
+ /**
+ * Map having ruleId as the key and coverage overview rule data as the value
+ */
+ rules_data: t.record(t.string, CoverageOverviewRuleAttributes),
+ })
+);
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/create_rule/create_rule_route.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/create_rule/create_rule_route.ts
new file mode 100644
index 0000000000000..cc71d7da3fbed
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/create_rule/create_rule_route.ts
@@ -0,0 +1,12 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type * as t from 'io-ts';
+import { RuleCreateProps } from '../../../model';
+
+export const CreateRuleRequestBody = RuleCreateProps;
+export type CreateRuleRequestBody = t.TypeOf;
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/create_rule/request_schema_validation.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/create_rule/request_schema_validation.test.ts
similarity index 96%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/create_rule/request_schema_validation.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/create_rule/request_schema_validation.test.ts
index 39ed8b028f054..733645dcb3aa9 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/create_rule/request_schema_validation.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/create_rule/request_schema_validation.test.ts
@@ -5,11 +5,11 @@
* 2.0.
*/
-import type { RuleCreateProps } from '../../../../../rule_schema';
+import type { RuleCreateProps } from '../../../model/rule_schema';
import {
getCreateRulesSchemaMock,
getCreateThreatMatchRulesSchemaMock,
-} from '../../../../../rule_schema/mocks';
+} from '../../../model/rule_schema/mocks';
import { validateCreateRuleProps } from './request_schema_validation';
describe('Create rule request schema, additional validation', () => {
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/create_rule/request_schema_validation.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/create_rule/request_schema_validation.ts
similarity index 97%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/create_rule/request_schema_validation.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/create_rule/request_schema_validation.ts
index fd2e4b06b63d6..519ef874c422e 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/create_rule/request_schema_validation.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/create_rule/request_schema_validation.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import type { RuleCreateProps } from '../../../../../rule_schema';
+import type { RuleCreateProps } from '../../../model';
/**
* Additional validation that is implemented outside of the schema itself.
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.mock.ts
similarity index 96%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.mock.ts
index 285e773456d98..4346c05333038 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.mock.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.mock.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import type { PatchRuleRequestBody, ThresholdPatchRuleRequestBody } from './request_schema';
+import type { PatchRuleRequestBody, ThresholdPatchRuleRequestBody } from './patch_rule_route';
export const getPatchRulesSchemaMock = (): PatchRuleRequestBody => ({
description: 'some description',
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.test.ts
similarity index 99%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.test.ts
index 36613736e3274..902b5d0c50899 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.test.ts
@@ -9,9 +9,9 @@ import { left } from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/pipeable';
import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils';
-import { getListArrayMock } from '../../../../../schemas/types/lists.mock';
-import { PatchRuleRequestBody } from './request_schema';
-import { getPatchRulesSchemaMock } from './request_schema.mock';
+import { getListArrayMock } from '../../../../../detection_engine/schemas/types/lists.mock';
+import { PatchRuleRequestBody } from './patch_rule_route';
+import { getPatchRulesSchemaMock } from './patch_rule_route.mock';
describe('Patch rule request schema', () => {
test('[id] does validate', () => {
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.ts
similarity index 96%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.ts
index 27a1f14687aa4..e74e406141c26 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { RulePatchProps, ThresholdRulePatchProps } from '../../../../../rule_schema';
+import { RulePatchProps, ThresholdRulePatchProps } from '../../../model';
/**
* Request body parameters of the API route.
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema_validation.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/request_schema_validation.test.ts
similarity index 98%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema_validation.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/request_schema_validation.test.ts
index c00e3c38fb91b..647bdd2c8be94 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema_validation.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/request_schema_validation.test.ts
@@ -5,8 +5,8 @@
* 2.0.
*/
-import type { PatchRuleRequestBody, ThresholdPatchRuleRequestBody } from './request_schema';
-import { getPatchRulesSchemaMock, getPatchThresholdRulesSchemaMock } from './request_schema.mock';
+import type { PatchRuleRequestBody, ThresholdPatchRuleRequestBody } from './patch_rule_route';
+import { getPatchRulesSchemaMock, getPatchThresholdRulesSchemaMock } from './patch_rule_route.mock';
import { validatePatchRuleRequestBody } from './request_schema_validation';
describe('Patch rule request schema, additional validation', () => {
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema_validation.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/request_schema_validation.ts
similarity index 97%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema_validation.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/request_schema_validation.ts
index 72d10bf5e58de..f27237b563b21 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema_validation.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/request_schema_validation.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import type { PatchRuleRequestBody } from './request_schema';
+import type { PatchRuleRequestBody } from './patch_rule_route';
/**
* Additional validation that is implemented outside of the schema itself.
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/read_rule/read_rule_route.ts
similarity index 53%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/index.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/read_rule/read_rule_route.ts
index d4b2fa83a4c58..e133c754ac327 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/index.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/read_rule/read_rule_route.ts
@@ -5,7 +5,8 @@
* 2.0.
*/
-export * from './api/create_rule_exceptions/request_schema';
-export * from './api/find_exception_references/request_schema';
-export * from './api/find_exception_references/response_schema';
-export * from './api/urls';
+import type * as t from 'io-ts';
+import { QueryRuleByIds } from '../../model/query_rule_by_ids';
+
+export const ReadRuleRequestQuery = QueryRuleByIds;
+export type ReadRuleRequestQuery = t.TypeOf;
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/update_rule/request_schema_validation.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/update_rule/request_schema_validation.test.ts
similarity index 95%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/update_rule/request_schema_validation.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/update_rule/request_schema_validation.test.ts
index f6a8d0bb39340..6bec7b1de3aba 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/update_rule/request_schema_validation.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/update_rule/request_schema_validation.test.ts
@@ -5,8 +5,8 @@
* 2.0.
*/
-import type { RuleUpdateProps } from '../../../../../rule_schema';
-import { getUpdateRulesSchemaMock } from '../../../../../rule_schema/mocks';
+import type { RuleUpdateProps } from '../../../model/rule_schema';
+import { getUpdateRulesSchemaMock } from '../../../model/rule_schema/mocks';
import { validateUpdateRuleProps } from './request_schema_validation';
describe('Update rule request schema, additional validation', () => {
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/update_rule/request_schema_validation.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/update_rule/request_schema_validation.ts
similarity index 97%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/update_rule/request_schema_validation.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/update_rule/request_schema_validation.ts
index 09d1e1e7b0a99..d58bbdc4bee05 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/update_rule/request_schema_validation.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/update_rule/request_schema_validation.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import type { RuleUpdateProps } from '../../../../../rule_schema';
+import type { RuleUpdateProps } from '../../../model';
/**
* Additional validation that is implemented outside of the schema itself.
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/update_rule/update_rule_route.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/update_rule/update_rule_route.ts
new file mode 100644
index 0000000000000..528dfd1d6f648
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/crud/update_rule/update_rule_route.ts
@@ -0,0 +1,12 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type * as t from 'io-ts';
+import { RuleUpdateProps } from '../../../model';
+
+export const UpdateRuleRequestBody = RuleUpdateProps;
+export type UpdateRuleRequestBody = t.TypeOf;
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/export/export_rules_details_schema.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_details_schema.mock.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/model/export/export_rules_details_schema.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_details_schema.mock.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/export/export_rules_details_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_details_schema.test.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/model/export/export_rules_details_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_details_schema.test.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/export/export_rules_details_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_details_schema.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/model/export/export_rules_details_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_details_schema.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/export_rules/request_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_route.test.ts
similarity index 98%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/export_rules/request_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_route.test.ts
index 0e0ec3cbaca3b..1edb1cfa499f0 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/export_rules/request_schema.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_route.test.ts
@@ -9,8 +9,8 @@ import { left } from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/pipeable';
import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils';
-import { ExportRulesRequestBody, ExportRulesRequestQuery } from './request_schema';
-import type { ExportRulesRequestQueryDecoded } from './request_schema';
+import { ExportRulesRequestBody, ExportRulesRequestQuery } from './export_rules_route';
+import type { ExportRulesRequestQueryDecoded } from './export_rules_route';
describe('Export rules request schema', () => {
describe('ExportRulesRequestBody', () => {
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/export_rules/request_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_route.ts
similarity index 89%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/export_rules/request_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_route.ts
index 682e69e55d5a4..00042f6ed554c 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/export_rules/request_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_route.ts
@@ -9,8 +9,8 @@ import * as t from 'io-ts';
import { DefaultExportFileName } from '@kbn/securitysolution-io-ts-alerting-types';
import { DefaultStringBooleanFalse } from '@kbn/securitysolution-io-ts-types';
-import type { FileName, ExcludeExportDetails } from '../../../../schemas/common/schemas';
-import { RuleSignatureId } from '../../../../rule_schema';
+import type { FileName, ExcludeExportDetails } from '../../model';
+import { RuleSignatureId } from '../../model';
const ObjectsWithRuleId = t.array(t.exact(t.type({ rule_id: RuleSignatureId })));
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/find_rules/request_schema.test.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/find_rules/request_schema.test.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/find_rules/request_schema.ts
similarity index 88%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/find_rules/request_schema.ts
index 08d05a54a5753..f97002f92d562 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/find_rules/request_schema.ts
@@ -7,8 +7,8 @@
import * as t from 'io-ts';
import { DefaultPerPage, DefaultPage } from '@kbn/securitysolution-io-ts-alerting-types';
-import type { PerPage, Page } from '../../../../schemas/common';
-import { queryFilter, fields, SortOrder } from '../../../../schemas/common';
+import type { PerPage, Page, RuleResponse } from '../../model';
+import { SortOrder, queryFilter, fields } from '../../model';
export type FindRulesSortField = t.TypeOf;
export const FindRulesSortField = t.union([
@@ -50,3 +50,10 @@ export type FindRulesRequestQueryDecoded = Omit {
test('it should validate an empty response with defaults', () => {
- const payload: RuleManagementFiltersResponse = {
+ const payload: GetRuleManagementFiltersResponse = {
rules_summary: {
custom_count: 0,
prebuilt_installed_count: 0,
@@ -21,7 +21,7 @@ describe('Rule management filters response schema', () => {
tags: [],
},
};
- const decoded = RuleManagementFiltersResponse.decode(payload);
+ const decoded = GetRuleManagementFiltersResponse.decode(payload);
const checked = exactCheck(payload, decoded);
const message = foldLeftRight(checked);
@@ -30,7 +30,7 @@ describe('Rule management filters response schema', () => {
});
test('it should validate an non empty response with defaults', () => {
- const payload: RuleManagementFiltersResponse = {
+ const payload: GetRuleManagementFiltersResponse = {
rules_summary: {
custom_count: 10,
prebuilt_installed_count: 20,
@@ -39,7 +39,7 @@ describe('Rule management filters response schema', () => {
tags: ['a', 'b', 'c'],
},
};
- const decoded = RuleManagementFiltersResponse.decode(payload);
+ const decoded = GetRuleManagementFiltersResponse.decode(payload);
const checked = exactCheck(payload, decoded);
const message = foldLeftRight(checked);
@@ -48,7 +48,7 @@ describe('Rule management filters response schema', () => {
});
test('it should not validate an extra invalid field added', () => {
- const payload: RuleManagementFiltersResponse & { invalid_field: string } = {
+ const payload: GetRuleManagementFiltersResponse & { invalid_field: string } = {
rules_summary: {
custom_count: 0,
prebuilt_installed_count: 0,
@@ -58,7 +58,7 @@ describe('Rule management filters response schema', () => {
},
invalid_field: 'invalid',
};
- const decoded = RuleManagementFiltersResponse.decode(payload);
+ const decoded = GetRuleManagementFiltersResponse.decode(payload);
const checked = exactCheck(payload, decoded);
const message = foldLeftRight(checked);
@@ -67,7 +67,7 @@ describe('Rule management filters response schema', () => {
});
test('it should NOT validate an empty response with a negative "summary.prebuilt_installed_count" number', () => {
- const payload: RuleManagementFiltersResponse = {
+ const payload: GetRuleManagementFiltersResponse = {
rules_summary: {
custom_count: 0,
prebuilt_installed_count: -1,
@@ -76,7 +76,7 @@ describe('Rule management filters response schema', () => {
tags: [],
},
};
- const decoded = RuleManagementFiltersResponse.decode(payload);
+ const decoded = GetRuleManagementFiltersResponse.decode(payload);
const checked = exactCheck(payload, decoded);
const message = foldLeftRight(checked);
@@ -87,7 +87,7 @@ describe('Rule management filters response schema', () => {
});
test('it should NOT validate an empty response with a negative "summary.custom_count"', () => {
- const payload: RuleManagementFiltersResponse = {
+ const payload: GetRuleManagementFiltersResponse = {
rules_summary: {
custom_count: -1,
prebuilt_installed_count: 0,
@@ -96,7 +96,7 @@ describe('Rule management filters response schema', () => {
tags: [],
},
};
- const decoded = RuleManagementFiltersResponse.decode(payload);
+ const decoded = GetRuleManagementFiltersResponse.decode(payload);
const checked = exactCheck(payload, decoded);
const message = foldLeftRight(checked);
@@ -107,7 +107,7 @@ describe('Rule management filters response schema', () => {
});
test('it should NOT validate an empty prepackaged response if "summary.prebuilt_installed_count" is not there', () => {
- const payload: RuleManagementFiltersResponse = {
+ const payload: GetRuleManagementFiltersResponse = {
rules_summary: {
custom_count: 0,
prebuilt_installed_count: 0,
@@ -118,7 +118,7 @@ describe('Rule management filters response schema', () => {
};
// @ts-expect-error
delete payload.rules_summary.prebuilt_installed_count;
- const decoded = RuleManagementFiltersResponse.decode(payload);
+ const decoded = GetRuleManagementFiltersResponse.decode(payload);
const checked = exactCheck(payload, decoded);
const message = foldLeftRight(checked);
@@ -129,7 +129,7 @@ describe('Rule management filters response schema', () => {
});
test('it should NOT validate an empty response with wrong "aggregated_fields.tags"', () => {
- const payload: RuleManagementFiltersResponse = {
+ const payload: GetRuleManagementFiltersResponse = {
rules_summary: {
custom_count: 0,
prebuilt_installed_count: 0,
@@ -139,7 +139,7 @@ describe('Rule management filters response schema', () => {
tags: [1],
},
};
- const decoded = RuleManagementFiltersResponse.decode(payload);
+ const decoded = GetRuleManagementFiltersResponse.decode(payload);
const checked = exactCheck(payload, decoded);
const message = foldLeftRight(checked);
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/filters/response_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/get_rule_management_filters/get_rule_management_filters_route.ts
similarity index 78%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/filters/response_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/get_rule_management_filters/get_rule_management_filters_route.ts
index 89d12bff729b3..bf786239d703d 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/filters/response_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/get_rule_management_filters/get_rule_management_filters_route.ts
@@ -8,8 +8,8 @@
import * as t from 'io-ts';
import { PositiveInteger } from '@kbn/securitysolution-io-ts-types';
-export type RuleManagementFiltersResponse = t.TypeOf;
-export const RuleManagementFiltersResponse = t.exact(
+export type GetRuleManagementFiltersResponse = t.TypeOf;
+export const GetRuleManagementFiltersResponse = t.exact(
t.type({
rules_summary: t.type({
custom_count: PositiveInteger,
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/import_rules_route.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/import_rules_route.test.ts
new file mode 100644
index 0000000000000..64630dca05610
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/import_rules_route.test.ts
@@ -0,0 +1,502 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { pipe } from 'fp-ts/lib/pipeable';
+import type { Either } from 'fp-ts/lib/Either';
+import { left } from 'fp-ts/lib/Either';
+import type { Errors } from 'io-ts';
+
+import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils';
+import type { ErrorSchema } from '../../model/error_schema';
+
+import { ImportRulesResponse } from './import_rules_route';
+
+describe('Import rules schema', () => {
+ describe('response schema', () => {
+ test('it should validate an empty import response with no errors', () => {
+ const payload: ImportRulesResponse = {
+ success: true,
+ success_count: 0,
+ rules_count: 0,
+ errors: [],
+ exceptions_errors: [],
+ exceptions_success: true,
+ exceptions_success_count: 0,
+ action_connectors_success: true,
+ action_connectors_success_count: 0,
+ action_connectors_errors: [],
+ action_connectors_warnings: [],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual([]);
+ expect(message.schema).toEqual(payload);
+ });
+
+ test('it should validate an empty import response with a single error', () => {
+ const payload: ImportRulesResponse = {
+ success: false,
+ success_count: 0,
+ rules_count: 0,
+ errors: [{ error: { status_code: 400, message: 'some message' } }],
+ exceptions_errors: [],
+ exceptions_success: true,
+ exceptions_success_count: 0,
+ action_connectors_success: true,
+ action_connectors_success_count: 0,
+ action_connectors_errors: [],
+ action_connectors_warnings: [],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual([]);
+ expect(message.schema).toEqual(payload);
+ });
+
+ test('it should validate an empty import response with a single exceptions error', () => {
+ const payload: ImportRulesResponse = {
+ success: false,
+ success_count: 0,
+ rules_count: 0,
+ errors: [],
+ exceptions_errors: [{ error: { status_code: 400, message: 'some message' } }],
+ exceptions_success: true,
+ exceptions_success_count: 0,
+ action_connectors_success: true,
+ action_connectors_success_count: 0,
+ action_connectors_errors: [],
+ action_connectors_warnings: [],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual([]);
+ expect(message.schema).toEqual(payload);
+ });
+
+ test('it should validate an empty import response with two errors', () => {
+ const payload: ImportRulesResponse = {
+ success: false,
+ success_count: 0,
+ rules_count: 0,
+ errors: [
+ { error: { status_code: 400, message: 'some message' } },
+ { error: { status_code: 500, message: 'some message' } },
+ ],
+ exceptions_errors: [],
+ exceptions_success: true,
+ exceptions_success_count: 0,
+ action_connectors_success: true,
+ action_connectors_success_count: 0,
+ action_connectors_errors: [],
+ action_connectors_warnings: [],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual([]);
+ expect(message.schema).toEqual(payload);
+ });
+
+ test('it should validate an empty import response with two exception errors', () => {
+ const payload: ImportRulesResponse = {
+ success: false,
+ success_count: 0,
+ rules_count: 0,
+ errors: [],
+ exceptions_errors: [
+ { error: { status_code: 400, message: 'some message' } },
+ { error: { status_code: 500, message: 'some message' } },
+ ],
+ exceptions_success: true,
+ exceptions_success_count: 0,
+ action_connectors_success: true,
+ action_connectors_success_count: 0,
+ action_connectors_errors: [],
+ action_connectors_warnings: [],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual([]);
+ expect(message.schema).toEqual(payload);
+ });
+
+ test('it should NOT validate a success_count that is a negative number', () => {
+ const payload: ImportRulesResponse = {
+ success: false,
+ success_count: -1,
+ rules_count: 0,
+ errors: [],
+ exceptions_errors: [],
+ exceptions_success: true,
+ exceptions_success_count: 0,
+ action_connectors_success: true,
+ action_connectors_success_count: 0,
+ action_connectors_errors: [],
+ action_connectors_warnings: [],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual([
+ 'Invalid value "-1" supplied to "success_count"',
+ ]);
+ expect(message.schema).toEqual({});
+ });
+
+ test('it should NOT validate a exceptions_success_count that is a negative number', () => {
+ const payload: ImportRulesResponse = {
+ success: false,
+ success_count: 0,
+ rules_count: 0,
+ errors: [],
+ exceptions_errors: [],
+ exceptions_success: true,
+ exceptions_success_count: -1,
+ action_connectors_success: true,
+ action_connectors_success_count: 0,
+ action_connectors_errors: [],
+ action_connectors_warnings: [],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual([
+ 'Invalid value "-1" supplied to "exceptions_success_count"',
+ ]);
+ expect(message.schema).toEqual({});
+ });
+
+ test('it should NOT validate a success that is not a boolean', () => {
+ type UnsafeCastForTest = Either<
+ Errors,
+ {
+ success: string;
+ success_count: number;
+ errors: Array<
+ {
+ id?: string | undefined;
+ rule_id?: string | undefined;
+ } & {
+ error: {
+ status_code: number;
+ message: string;
+ };
+ }
+ >;
+ }
+ >;
+ const payload: Omit & { success: string } = {
+ success: 'hello',
+ success_count: 0,
+ rules_count: 0,
+ errors: [],
+ exceptions_errors: [],
+ exceptions_success: true,
+ exceptions_success_count: 0,
+ action_connectors_success: true,
+ action_connectors_success_count: 0,
+ action_connectors_errors: [],
+ action_connectors_warnings: [],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded as UnsafeCastForTest);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual([
+ 'Invalid value "hello" supplied to "success"',
+ ]);
+ expect(message.schema).toEqual({});
+ });
+
+ test('it should NOT validate a exceptions_success that is not a boolean', () => {
+ type UnsafeCastForTest = Either<
+ Errors,
+ {
+ success: boolean;
+ exceptions_success: string;
+ success_count: number;
+ errors: Array<
+ {
+ id?: string | undefined;
+ rule_id?: string | undefined;
+ } & {
+ error: {
+ status_code: number;
+ message: string;
+ };
+ }
+ >;
+ }
+ >;
+ const payload: Omit & {
+ exceptions_success: string;
+ } = {
+ success: true,
+ success_count: 0,
+ rules_count: 0,
+ errors: [],
+ exceptions_errors: [],
+ exceptions_success: 'hello',
+ exceptions_success_count: 0,
+ action_connectors_success: true,
+ action_connectors_success_count: 0,
+ action_connectors_errors: [],
+ action_connectors_warnings: [],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded as UnsafeCastForTest);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual([
+ 'Invalid value "hello" supplied to "exceptions_success"',
+ ]);
+ expect(message.schema).toEqual({});
+ });
+
+ test('it should NOT validate a success an extra invalid field', () => {
+ const payload: ImportRulesResponse & { invalid_field: string } = {
+ success: true,
+ success_count: 0,
+ rules_count: 0,
+ errors: [],
+ invalid_field: 'invalid_data',
+ exceptions_errors: [],
+ exceptions_success: true,
+ exceptions_success_count: 0,
+ action_connectors_success: true,
+ action_connectors_success_count: 0,
+ action_connectors_errors: [],
+ action_connectors_warnings: [],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual(['invalid keys "invalid_field"']);
+ expect(message.schema).toEqual({});
+ });
+
+ test('it should NOT validate an extra field in the second position of the errors array', () => {
+ type InvalidError = ErrorSchema & { invalid_data?: string };
+ const payload: Omit & {
+ errors: InvalidError[];
+ } = {
+ success: true,
+ success_count: 0,
+ rules_count: 0,
+ errors: [
+ { error: { status_code: 400, message: 'some message' } },
+ { invalid_data: 'something', error: { status_code: 500, message: 'some message' } },
+ ],
+ exceptions_errors: [],
+ exceptions_success: true,
+ exceptions_success_count: 0,
+ action_connectors_success: true,
+ action_connectors_success_count: 0,
+ action_connectors_errors: [],
+ action_connectors_warnings: [],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual(['invalid keys "invalid_data"']);
+ expect(message.schema).toEqual({});
+ });
+
+ test('it should validate an empty import response with a single connectors error', () => {
+ const payload: ImportRulesResponse = {
+ success: false,
+ success_count: 0,
+ rules_count: 0,
+ errors: [],
+ exceptions_errors: [],
+ exceptions_success: true,
+ exceptions_success_count: 0,
+ action_connectors_success: true,
+ action_connectors_success_count: 0,
+ action_connectors_errors: [{ error: { status_code: 400, message: 'some message' } }],
+ action_connectors_warnings: [],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual([]);
+ expect(message.schema).toEqual(payload);
+ });
+ test('it should validate an empty import response with multiple errors', () => {
+ const payload: ImportRulesResponse = {
+ success: false,
+ success_count: 0,
+ rules_count: 0,
+ errors: [
+ { error: { status_code: 400, message: 'some message' } },
+ { error: { status_code: 500, message: 'some message' } },
+ ],
+ exceptions_errors: [],
+ exceptions_success: true,
+ exceptions_success_count: 0,
+ action_connectors_success: true,
+ action_connectors_success_count: 0,
+ action_connectors_errors: [{ error: { status_code: 400, message: 'some message' } }],
+ action_connectors_warnings: [],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual([]);
+ expect(message.schema).toEqual(payload);
+ });
+ test('it should NOT validate action_connectors_success that is not boolean', () => {
+ type UnsafeCastForTest = Either<
+ Errors,
+ {
+ success: boolean;
+ action_connectors_success: string;
+ success_count: number;
+ errors: Array<
+ {
+ id?: string | undefined;
+ rule_id?: string | undefined;
+ } & {
+ error: {
+ status_code: number;
+ message: string;
+ };
+ }
+ >;
+ }
+ >;
+ const payload: Omit & {
+ action_connectors_success: string;
+ } = {
+ success: true,
+ success_count: 0,
+ rules_count: 0,
+ errors: [],
+ exceptions_errors: [],
+ exceptions_success: true,
+ exceptions_success_count: 0,
+ action_connectors_success: 'invalid',
+ action_connectors_success_count: 0,
+ action_connectors_errors: [],
+ action_connectors_warnings: [],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded as UnsafeCastForTest);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual([
+ 'Invalid value "invalid" supplied to "action_connectors_success"',
+ ]);
+ expect(message.schema).toEqual({});
+ });
+ test('it should NOT validate a action_connectors_success_count that is a negative number', () => {
+ const payload: ImportRulesResponse = {
+ success: false,
+ success_count: 0,
+ rules_count: 0,
+ errors: [],
+ exceptions_errors: [],
+ exceptions_success: true,
+ exceptions_success_count: 0,
+ action_connectors_success: true,
+ action_connectors_success_count: -1,
+ action_connectors_errors: [],
+ action_connectors_warnings: [],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual([
+ 'Invalid value "-1" supplied to "action_connectors_success_count"',
+ ]);
+ expect(message.schema).toEqual({});
+ });
+ test('it should validate a action_connectors_warnings after importing successfully', () => {
+ const payload: ImportRulesResponse = {
+ success: false,
+ success_count: 0,
+ rules_count: 0,
+ errors: [],
+ exceptions_errors: [],
+ exceptions_success: true,
+ exceptions_success_count: 0,
+ action_connectors_success: true,
+ action_connectors_success_count: 1,
+ action_connectors_errors: [],
+ action_connectors_warnings: [
+ { type: 'type', message: 'message', actionPath: 'actionPath' },
+ ],
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual([]);
+ expect(message.schema).toEqual(payload);
+ });
+ test('it should NOT validate a action_connectors_warnings that is not WarningSchema', () => {
+ type UnsafeCastForTest = Either<
+ Errors,
+ {
+ success: boolean;
+ action_connectors_warnings: string;
+ success_count: number;
+ errors: Array<
+ {
+ id?: string | undefined;
+ rule_id?: string | undefined;
+ } & {
+ error: {
+ status_code: number;
+ message: string;
+ };
+ }
+ >;
+ }
+ >;
+ const payload: Omit & {
+ action_connectors_warnings: string;
+ } = {
+ success: true,
+ success_count: 0,
+ rules_count: 0,
+ errors: [],
+ exceptions_errors: [],
+ exceptions_success: true,
+ exceptions_success_count: 0,
+ action_connectors_success: true,
+ action_connectors_success_count: 0,
+ action_connectors_errors: [],
+ action_connectors_warnings: 'invalid',
+ };
+ const decoded = ImportRulesResponse.decode(payload);
+ const checked = exactCheck(payload, decoded as UnsafeCastForTest);
+ const message = pipe(checked, foldLeftRight);
+
+ expect(getPaths(left(message.errors))).toEqual([
+ 'Invalid value "invalid" supplied to "action_connectors_warnings"',
+ ]);
+ expect(message.schema).toEqual({});
+ });
+ });
+});
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/import_rules/response_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/import_rules_route.ts
similarity index 52%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/import_rules/response_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/import_rules_route.ts
index 99212b902c4d3..46e8721c45679 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/import_rules/response_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/import_rules_route.ts
@@ -6,8 +6,28 @@
*/
import * as t from 'io-ts';
-import { PositiveInteger } from '@kbn/securitysolution-io-ts-types';
-import { errorSchema, warningSchema } from '../../../../schemas/response';
+import { DefaultStringBooleanFalse, PositiveInteger } from '@kbn/securitysolution-io-ts-types';
+import { errorSchema, warningSchema } from '../../model';
+
+export const ImportRulesRequestQuery = t.exact(
+ t.partial({
+ overwrite: DefaultStringBooleanFalse,
+ overwrite_exceptions: DefaultStringBooleanFalse,
+ overwrite_action_connectors: DefaultStringBooleanFalse,
+ as_new_list: DefaultStringBooleanFalse,
+ })
+);
+
+export type ImportRulesRequestQuery = t.TypeOf;
+export type ImportRulesRequestQueryDecoded = Omit<
+ ImportRulesRequestQuery,
+ 'overwrite' | 'overwrite_exceptions' | 'as_new_list' | 'overwrite_action_connectors'
+> & {
+ overwrite: boolean;
+ overwrite_exceptions: boolean;
+ overwrite_action_connectors: boolean;
+ as_new_list: boolean;
+};
export type ImportRulesResponse = t.TypeOf;
export const ImportRulesResponse = t.exact(
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/rule_to_import.mock.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/rule_to_import.mock.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/rule_to_import.test.ts
similarity index 99%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/rule_to_import.test.ts
index 84478b4af27fe..29ad45c10bf84 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/rule_to_import.test.ts
@@ -9,7 +9,7 @@ import { left } from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/pipeable';
import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils';
-import { getListArrayMock } from '../../../schemas/types/lists.mock';
+import { getListArrayMock } from '../../../../detection_engine/schemas/types/lists.mock';
import { RuleToImport } from './rule_to_import';
import {
getImportRulesSchemaMock,
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/rule_to_import.ts
similarity index 92%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/rule_to_import.ts
index 8d9cee09a9f7b..1b01d913eaee2 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/rule_to_import.ts
@@ -16,8 +16,12 @@ import {
SetupGuide,
BaseCreateProps,
TypeSpecificCreateProps,
-} from '../../../rule_schema';
-import { created_at, updated_at, created_by, updated_by, revision } from '../../../schemas/common';
+ created_at,
+ updated_at,
+ created_by,
+ updated_by,
+ revision,
+} from '../../model';
/**
* Differences from this and the createRulesSchema are
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import_validation.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/rule_to_import_validation.test.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import_validation.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/rule_to_import_validation.test.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import_validation.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/rule_to_import_validation.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import_validation.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/rule_to_import_validation.ts
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/index.ts
new file mode 100644
index 0000000000000..bd9066d90a96e
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/index.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './bulk_actions/bulk_actions_route';
+export * from './bulk_crud/bulk_create_rules/bulk_create_rules_route';
+export * from './bulk_crud/bulk_delete_rules/bulk_delete_rules_route';
+export * from './bulk_crud/bulk_patch_rules/bulk_patch_rules_route';
+export * from './bulk_crud/bulk_update_rules/bulk_update_rules_route';
+export * from './bulk_crud/response_schema';
+export * from './coverage_overview/coverage_overview_route';
+export * from './crud/create_rule/request_schema_validation';
+export * from './crud/patch_rule/request_schema_validation';
+export * from './crud/patch_rule/patch_rule_route';
+export * from './crud/read_rule/read_rule_route';
+export * from './crud/update_rule/update_rule_route';
+export * from './crud/update_rule/request_schema_validation';
+export * from './export_rules/export_rules_details_schema';
+export * from './export_rules/export_rules_route';
+export * from './get_rule_management_filters/get_rule_management_filters_route';
+export * from './find_rules/request_schema';
+export * from './find_rules/request_schema_validation';
+export * from './import_rules/import_rules_route';
+export * from './import_rules/rule_to_import_validation';
+export * from './import_rules/rule_to_import';
+export * from './urls';
+export * from './model/query_rule_by_ids';
+export * from './model/query_rule_by_ids_validation';
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/mocks.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/mocks.ts
new file mode 100644
index 0000000000000..24e6f6120238b
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/mocks.ts
@@ -0,0 +1,12 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './bulk_actions/bulk_actions_route.mock';
+export * from './crud/patch_rule/patch_rule_route.mock';
+
+export * from './export_rules/export_rules_details_schema.mock';
+export * from './import_rules/rule_to_import.mock';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/model/query_rule_by_ids.test.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/model/query_rule_by_ids.test.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/model/query_rule_by_ids.ts
similarity index 85%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/model/query_rule_by_ids.ts
index d52d8c66125e6..2de0116d2875f 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/model/query_rule_by_ids.ts
@@ -6,7 +6,7 @@
*/
import * as t from 'io-ts';
-import { RuleObjectId, RuleSignatureId } from '../../../../../rule_schema';
+import { RuleObjectId, RuleSignatureId } from '../../model';
export type QueryRuleByIds = t.TypeOf;
export const QueryRuleByIds = t.exact(
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids_validation.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/model/query_rule_by_ids_validation.test.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids_validation.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/model/query_rule_by_ids_validation.test.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids_validation.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/model/query_rule_by_ids_validation.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids_validation.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/model/query_rule_by_ids_validation.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/urls.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_management/urls.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/api/urls.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_management/urls.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/detection_engine_health/README.md b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/README.md
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/detection_engine_health/README.md
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/README.md
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/detection_engine_health/get_cluster_health_schemas.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/get_cluster_health/get_cluster_health_route.ts
similarity index 83%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/detection_engine_health/get_cluster_health_schemas.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/get_cluster_health/get_cluster_health_route.ts
index a4b28a2d1bc31..dafa1e4a4a1df 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/detection_engine_health/get_cluster_health_schemas.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/get_cluster_health/get_cluster_health_route.ts
@@ -7,13 +7,13 @@
import * as t from 'io-ts';
import type { IsoDateString } from '@kbn/securitysolution-io-ts-types';
-import type { HealthInterval } from '../../model/detection_engine_health/health_interval';
-import { HealthIntervalParameters } from '../../model/detection_engine_health/health_interval';
-import type { HealthTimings } from '../../model/detection_engine_health/health_metadata';
import type {
ClusterHealthParameters,
ClusterHealthSnapshot,
-} from '../../model/detection_engine_health/cluster_health';
+ HealthInterval,
+ HealthTimings,
+} from '../model';
+import { HealthIntervalParameters } from '../model';
/**
* Schema for the request body of the endpoint.
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/detection_engine_health/get_rule_health_schemas.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/get_rule_health/get_rule_health_route.ts
similarity index 84%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/detection_engine_health/get_rule_health_schemas.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/get_rule_health/get_rule_health_route.ts
index 8f810549f54ee..c3c32edfd9a19 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/detection_engine_health/get_rule_health_schemas.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/get_rule_health/get_rule_health_route.ts
@@ -9,13 +9,13 @@ import * as t from 'io-ts';
import type { IsoDateString } from '@kbn/securitysolution-io-ts-types';
import { NonEmptyString } from '@kbn/securitysolution-io-ts-types';
-import type { HealthInterval } from '../../model/detection_engine_health/health_interval';
-import { HealthIntervalParameters } from '../../model/detection_engine_health/health_interval';
-import type { HealthTimings } from '../../model/detection_engine_health/health_metadata';
import type {
+ HealthInterval,
+ HealthTimings,
RuleHealthParameters,
RuleHealthSnapshot,
-} from '../../model/detection_engine_health/rule_health';
+} from '../model';
+import { HealthIntervalParameters } from '../model';
/**
* Schema for the request body of the endpoint.
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/detection_engine_health/get_space_health_schemas.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/get_space_health/get_space_health_route.ts
similarity index 82%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/detection_engine_health/get_space_health_schemas.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/get_space_health/get_space_health_route.ts
index 4ad9a95a3f938..fe10178e5de9d 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/detection_engine_health/get_space_health_schemas.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/get_space_health/get_space_health_route.ts
@@ -7,13 +7,13 @@
import * as t from 'io-ts';
import type { IsoDateString } from '@kbn/securitysolution-io-ts-types';
-import type { HealthInterval } from '../../model/detection_engine_health/health_interval';
-import { HealthIntervalParameters } from '../../model/detection_engine_health/health_interval';
-import type { HealthTimings } from '../../model/detection_engine_health/health_metadata';
import type {
+ HealthInterval,
+ HealthTimings,
SpaceHealthParameters,
SpaceHealthSnapshot,
-} from '../../model/detection_engine_health/space_health';
+} from '../model';
+import { HealthIntervalParameters } from '../model';
/**
* Schema for the request body of the endpoint.
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/cluster_health.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/cluster_health.mock.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/cluster_health.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/cluster_health.mock.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/cluster_health.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/cluster_health.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/cluster_health.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/cluster_health.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/health_interval.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/health_interval.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/health_interval.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/health_interval.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/health_metadata.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/health_metadata.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/health_metadata.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/health_metadata.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/health_stats.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/health_stats.mock.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/health_stats.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/health_stats.mock.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/health_stats.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/health_stats.ts
similarity index 99%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/health_stats.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/health_stats.ts
index e43a5bfbd3073..4af7ea8c6bd07 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/health_stats.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/health_stats.ts
@@ -7,7 +7,7 @@
import type { IsoDateString } from '@kbn/securitysolution-io-ts-types';
import type { RuleLastRunOutcomes } from '@kbn/alerting-plugin/common';
-import type { LogLevel } from '../log_level';
+import type { LogLevel } from '../../model';
// -------------------------------------------------------------------------------------------------
// Stats history (date histogram)
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/index.ts
new file mode 100644
index 0000000000000..10d72d2241ec0
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/index.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
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './cluster_health';
+export * from './health_interval';
+export * from './health_metadata';
+export * from './health_stats';
+export * from './rule_health';
+export * from './space_health';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/rule_health.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/rule_health.mock.ts
similarity index 92%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/rule_health.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/rule_health.mock.ts
index 2ae5b8a7a8205..961a057b2603e 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/rule_health.mock.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/rule_health.mock.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { getRulesSchemaMock } from '../../../rule_schema/mocks';
+import { getRulesSchemaMock } from '../../../model/rule_schema/mocks';
import { healthStatsMock } from './health_stats.mock';
import type { RuleHealthSnapshot } from './rule_health';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/rule_health.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/rule_health.ts
similarity index 94%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/rule_health.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/rule_health.ts
index b0b3577a46967..59756df926e27 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/rule_health.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/rule_health.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import type { RuleResponse } from '../../../rule_schema/model/rule_schemas';
+import type { RuleResponse } from '../../../model';
import type { HealthParameters, HealthSnapshot } from './health_metadata';
import type { RuleExecutionStats, StatsHistory } from './health_stats';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/space_health.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/space_health.mock.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/space_health.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/space_health.mock.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/space_health.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/space_health.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/detection_engine_health/space_health.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/detection_engine_health/model/space_health.ts
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/index.ts
new file mode 100644
index 0000000000000..a2f5f76f00b08
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/index.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
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './detection_engine_health/get_cluster_health/get_cluster_health_route';
+export * from './detection_engine_health/get_rule_health/get_rule_health_route';
+export * from './detection_engine_health/get_space_health/get_space_health_route';
+export * from './detection_engine_health/model';
+export * from './rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route';
+export * from './rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route';
+export * from './urls';
+
+export * from './model/execution_event';
+export * from './model/execution_metrics';
+export * from './model/execution_result';
+export * from './model/execution_settings';
+export * from './model/execution_status';
+export * from './model/execution_summary';
+export * from './model/log_level';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/mocks.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/mocks.ts
similarity index 50%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/mocks.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/mocks.ts
index 1a93749849cdf..0c8c7a1cafad3 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/mocks.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/mocks.ts
@@ -5,12 +5,12 @@
* 2.0.
*/
-export * from './api/rule_execution_logs/get_rule_execution_events_schemas.mock';
-export * from './api/rule_execution_logs/get_rule_execution_results_schemas.mock';
+export * from './rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route.mock';
+export * from './rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.mock';
-export * from './model/detection_engine_health/cluster_health.mock';
-export * from './model/detection_engine_health/rule_health.mock';
-export * from './model/detection_engine_health/space_health.mock';
+export * from './detection_engine_health/model/cluster_health.mock';
+export * from './detection_engine_health/model/rule_health.mock';
+export * from './detection_engine_health/model/space_health.mock';
export * from './model/execution_event.mock';
export * from './model/execution_result.mock';
export * from './model/execution_summary.mock';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_event.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_event.mock.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_event.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_event.mock.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_event.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_event.ts
similarity index 96%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_event.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_event.ts
index 0e269b39ff8f1..3eaa2ca7efad0 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_event.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_event.ts
@@ -7,7 +7,7 @@
import * as t from 'io-ts';
import { enumeration, IsoDateString } from '@kbn/securitysolution-io-ts-types';
-import { enumFromString } from '../../../utils/enum_from_string';
+import { enumFromString } from '../../../../utils/enum_from_string';
import { TLogLevel } from './log_level';
/**
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_metrics.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_metrics.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_metrics.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_metrics.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_result.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_result.mock.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_result.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_result.mock.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_result.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_result.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_result.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_result.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_settings.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_settings.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_settings.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_settings.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_status.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_status.ts
similarity index 98%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_status.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_status.ts
index af5049c8f9bf0..1e95e3a812054 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_status.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_status.ts
@@ -8,7 +8,7 @@
import type * as t from 'io-ts';
import { enumeration, PositiveInteger } from '@kbn/securitysolution-io-ts-types';
import type { RuleLastRunOutcomes } from '@kbn/alerting-plugin/common';
-import { assertUnreachable } from '../../../utility_types';
+import { assertUnreachable } from '../../../../utility_types';
/**
* Custom execution status of Security rules that is different from the status
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_summary.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_summary.mock.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_summary.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_summary.mock.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_summary.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_summary.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_summary.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_summary.ts
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/index.ts
new file mode 100644
index 0000000000000..b486b9d80957a
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/index.ts
@@ -0,0 +1,14 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './execution_event';
+export * from './execution_metrics';
+export * from './execution_result';
+export * from './execution_settings';
+export * from './execution_status';
+export * from './execution_summary';
+export * from './log_level';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/log_level.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/log_level.ts
similarity index 93%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/log_level.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/log_level.ts
index b37ce62ad4891..9add3b46b3ef3 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/log_level.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/log_level.ts
@@ -6,8 +6,8 @@
*/
import { enumeration } from '@kbn/securitysolution-io-ts-types';
-import { enumFromString } from '../../../utils/enum_from_string';
-import { assertUnreachable } from '../../../utility_types';
+import { enumFromString } from '../../../../utils/enum_from_string';
+import { assertUnreachable } from '../../../../utility_types';
import { RuleExecutionStatus } from './execution_status';
export enum LogLevel {
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_events_schemas.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route.mock.ts
similarity index 96%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_events_schemas.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route.mock.ts
index 4d647b5f10094..b46f8d9b13870 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_events_schemas.mock.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route.mock.ts
@@ -6,7 +6,7 @@
*/
import { ruleExecutionEventMock } from '../../model/execution_event.mock';
-import type { GetRuleExecutionEventsResponse } from './get_rule_execution_events_schemas';
+import type { GetRuleExecutionEventsResponse } from './get_rule_execution_events_route';
const getSomeResponse = (): GetRuleExecutionEventsResponse => {
const events = ruleExecutionEventMock.getSomeEvents();
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_events_schemas.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route.test.ts
similarity index 99%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_events_schemas.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route.test.ts
index 89b7b992fbbad..ecf94032039ac 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_events_schemas.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route.test.ts
@@ -12,7 +12,7 @@ import { foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils';
import {
GetRuleExecutionEventsRequestParams,
GetRuleExecutionEventsRequestQuery,
-} from './get_rule_execution_events_schemas';
+} from './get_rule_execution_events_route';
describe('Request schema of Get rule execution events', () => {
describe('GetRuleExecutionEventsRequestParams', () => {
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_events_schemas.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route.ts
similarity index 90%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_events_schemas.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route.ts
index 8c3c76e2286d9..9f5bd8d273efc 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_events_schemas.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route.ts
@@ -10,9 +10,8 @@ import * as t from 'io-ts';
import { DefaultPerPage, DefaultPage } from '@kbn/securitysolution-io-ts-alerting-types';
import { defaultCsvArray, NonEmptyString } from '@kbn/securitysolution-io-ts-types';
-import { DefaultSortOrderDesc, PaginationResult } from '../../../schemas/common';
-import { RuleExecutionEvent, TRuleExecutionEventType } from '../../model/execution_event';
-import { TLogLevel } from '../../model/log_level';
+import { DefaultSortOrderDesc, PaginationResult } from '../../../model';
+import { RuleExecutionEvent, TRuleExecutionEventType, TLogLevel } from '../../model';
/**
* URL path parameters of the API route.
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_results_schemas.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.mock.ts
similarity index 95%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_results_schemas.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.mock.ts
index b8e323e6fb1f3..9584616343332 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_results_schemas.mock.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.mock.ts
@@ -6,7 +6,7 @@
*/
import { ruleExecutionResultMock } from '../../model/execution_result.mock';
-import type { GetRuleExecutionResultsResponse } from './get_rule_execution_results_schemas';
+import type { GetRuleExecutionResultsResponse } from './get_rule_execution_results_route';
const getSomeResponse = (): GetRuleExecutionResultsResponse => {
const results = ruleExecutionResultMock.getSomeResults();
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_results_schemas.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.test.ts
similarity index 99%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_results_schemas.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.test.ts
index 375047b935d24..53ed03003487e 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_results_schemas.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.test.ts
@@ -13,7 +13,7 @@ import { RULE_EXECUTION_STATUSES } from '../../model/execution_status';
import {
DefaultSortField,
DefaultRuleExecutionStatusCsvArray,
-} from './get_rule_execution_results_schemas';
+} from './get_rule_execution_results_route';
describe('Request schema of Get rule execution results', () => {
describe('DefaultRuleExecutionStatusCsvArray', () => {
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_results_schemas.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.ts
similarity index 91%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_results_schemas.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.ts
index e2cec9b7a3b29..56370acbce5bd 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_results_schemas.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.ts
@@ -16,9 +16,12 @@ import {
NonEmptyString,
} from '@kbn/securitysolution-io-ts-types';
-import { DefaultSortOrderDesc } from '../../../schemas/common';
-import { RuleExecutionResult, SortFieldOfRuleExecutionResult } from '../../model/execution_result';
-import { TRuleExecutionStatus } from '../../model/execution_status';
+import { DefaultSortOrderDesc } from '../../../model';
+import {
+ RuleExecutionResult,
+ SortFieldOfRuleExecutionResult,
+ TRuleExecutionStatus,
+} from '../../model';
/**
* Types the DefaultRuleExecutionStatusCsvArray as:
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/urls.ts b/x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/urls.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/urls.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/rule_monitoring/urls.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals/index.ts
similarity index 57%
rename from x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/index.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/signals/index.ts
index 20669682c63f9..636728ee2525d 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/index.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/signals/index.ts
@@ -5,6 +5,6 @@
* 2.0.
*/
-export * from './api/get_prebuilt_rules_and_timelines_status/response_schema';
-export * from './api/install_prebuilt_rules_and_timelines/response_schema';
-export * from './api/urls';
+export * from './query_signals/query_signals_route';
+export * from './set_signal_status/set_signal_status_route';
+export * from './set_signal_status/set_signal_status_type_dependents';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_signals_index_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals/query_signals/query_signals_route.test.ts
similarity index 96%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_signals_index_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/signals/query_signals/query_signals_route.test.ts
index 41677055d6adf..6afdc9a07e8ab 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_signals_index_schema.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/signals/query_signals/query_signals_route.test.ts
@@ -5,8 +5,8 @@
* 2.0.
*/
-import type { QuerySignalsSchema } from './query_signals_index_schema';
-import { querySignalsSchema } from './query_signals_index_schema';
+import type { QuerySignalsSchema } from './query_signals_route';
+import { querySignalsSchema } from './query_signals_route';
import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils';
import { pipe } from 'fp-ts/lib/pipeable';
import { left } from 'fp-ts/lib/Either';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_signals_index_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals/query_signals/query_signals_route.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_signals_index_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/signals/query_signals/query_signals_route.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signal_status_route.test.ts
similarity index 97%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signal_status_route.test.ts
index ef5353c91213c..3f9e432fbc4f9 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signal_status_route.test.ts
@@ -5,8 +5,8 @@
* 2.0.
*/
-import type { SetSignalsStatusSchema } from './set_signal_status_schema';
-import { setSignalsStatusSchema } from './set_signal_status_schema';
+import type { SetSignalsStatusSchema } from './set_signal_status_route';
+import { setSignalsStatusSchema } from './set_signal_status_route';
import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils';
import { pipe } from 'fp-ts/lib/pipeable';
import { left } from 'fp-ts/lib/Either';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signal_status_route.ts
similarity index 96%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signal_status_route.ts
index e6f07f973a098..78d62031d5eb3 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signal_status_route.ts
@@ -7,7 +7,7 @@
import * as t from 'io-ts';
-import { conflicts, signal_ids, signal_status_query, status } from '../common/schemas';
+import { conflicts, signal_ids, signal_status_query, status } from '../../model';
export const setSignalsStatusSchema = t.intersection([
t.type({
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_type_dependents.test.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signal_status_type_dependents.test.ts
similarity index 99%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_type_dependents.test.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signal_status_type_dependents.test.ts
index efe5e6cedd303..97cf74435c294 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_type_dependents.test.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signal_status_type_dependents.test.ts
@@ -6,7 +6,7 @@
*/
import { setSignalStatusValidateTypeDependents } from './set_signal_status_type_dependents';
-import type { SetSignalsStatusSchema } from './set_signal_status_schema';
+import type { SetSignalsStatusSchema } from './set_signal_status_route';
describe('update_rules_type_dependents', () => {
test('You can have just a "signals_id"', () => {
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_type_dependents.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signal_status_type_dependents.ts
similarity index 98%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_type_dependents.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signal_status_type_dependents.ts
index 38ec66493ea39..a484fde33d107 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_type_dependents.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signal_status_type_dependents.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import type { SetSignalsStatusSchema } from './set_signal_status_schema';
+import type { SetSignalsStatusSchema } from './set_signal_status_route';
export const validateId = (signalStatus: SetSignalsStatusSchema): string[] => {
if (signalStatus.signal_ids != null && signalStatus.query != null) {
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_signals_migration_schema.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/create_signals_migration/create_signals_migration_route.mock.ts
similarity index 95%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_signals_migration_schema.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/create_signals_migration/create_signals_migration_route.mock.ts
index 19b409e8eab95..ccb5543ef72d2 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_signals_migration_schema.mock.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/create_signals_migration/create_signals_migration_route.mock.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import type { CreateSignalsMigrationSchema } from './create_signals_migration_schema';
+import type { CreateSignalsMigrationSchema } from './create_signals_migration_route';
export const getCreateSignalsMigrationSchemaMock = (
index: string = 'signals-index'
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_signals_migration_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/create_signals_migration/create_signals_migration_route.ts
similarity index 94%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_signals_migration_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/create_signals_migration/create_signals_migration_route.ts
index 1eba4855bf0d3..cb67964ea7745 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_signals_migration_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/create_signals_migration/create_signals_migration_route.ts
@@ -8,7 +8,7 @@
import * as t from 'io-ts';
import { PositiveInteger, PositiveIntegerGreaterThanZero } from '@kbn/securitysolution-io-ts-types';
-import { IndexPatternArray } from '../../rule_schema';
+import { IndexPatternArray } from '../../model';
export const signalsReindexOptions = t.partial({
requests_per_second: t.number,
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/delete_signals_migration_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/delete_signals_migration/delete_signals_migration_route.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/delete_signals_migration_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/delete_signals_migration/delete_signals_migration_route.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/finalize_signals_migration_schema.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/finalize_signals_migration/finalize_signals_migration_route.mock.ts
similarity index 94%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/finalize_signals_migration_schema.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/finalize_signals_migration/finalize_signals_migration_route.mock.ts
index b6b7a54cd533b..25d66c5b68d09 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/finalize_signals_migration_schema.mock.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/finalize_signals_migration/finalize_signals_migration_route.mock.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import type { FinalizeSignalsMigrationSchema } from './finalize_signals_migration_schema';
+import type { FinalizeSignalsMigrationSchema } from './finalize_signals_migration_route';
export const getFinalizeSignalsMigrationSchemaMock = (): FinalizeSignalsMigrationSchema => ({
migration_ids: ['migrationSOIdentifier'],
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/finalize_signals_migration_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/finalize_signals_migration/finalize_signals_migration_route.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/finalize_signals_migration_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/finalize_signals_migration/finalize_signals_migration_route.ts
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/get_signals_migration_status_schema.mock.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/get_signals_migration_status/get_signals_migration_status_route.mock.ts
similarity index 93%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/get_signals_migration_status_schema.mock.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/get_signals_migration_status/get_signals_migration_status_route.mock.ts
index 0de1cf9ea8456..8cc78ffa9700e 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/get_signals_migration_status_schema.mock.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/get_signals_migration_status/get_signals_migration_status_route.mock.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import type { GetSignalsMigrationStatusSchema } from './get_signals_migration_status_schema';
+import type { GetSignalsMigrationStatusSchema } from './get_signals_migration_status_route';
export const getSignalsMigrationStatusSchemaMock = (): GetSignalsMigrationStatusSchema => ({
from: 'now-30d',
diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/get_signals_migration_status_schema.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/get_signals_migration_status/get_signals_migration_status_route.ts
similarity index 100%
rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/get_signals_migration_status_schema.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/get_signals_migration_status/get_signals_migration_status_route.ts
diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/index.ts
new file mode 100644
index 0000000000000..78452dc62f46c
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/index.ts
@@ -0,0 +1,11 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './create_signals_migration/create_signals_migration_route';
+export * from './delete_signals_migration/delete_signals_migration_route';
+export * from './finalize_signals_migration/finalize_signals_migration_route';
+export * from './get_signals_migration_status/get_signals_migration_status_route';
diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/mocks.ts b/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/mocks.ts
similarity index 50%
rename from x-pack/plugins/security_solution/common/detection_engine/rule_management/mocks.ts
rename to x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/mocks.ts
index 6827236f8dcbf..90713ec3a1881 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/mocks.ts
+++ b/x-pack/plugins/security_solution/common/api/detection_engine/signals_migration/mocks.ts
@@ -5,8 +5,6 @@
* 2.0.
*/
-export * from './api/rules/bulk_actions/request_schema.mock';
-export * from './api/rules/crud/patch_rule/request_schema.mock';
-
-export * from './model/export/export_rules_details_schema.mock';
-export * from './model/import/rule_to_import.mock';
+export * from './create_signals_migration/create_signals_migration_route.mock';
+export * from './finalize_signals_migration/finalize_signals_migration_route.mock';
+export * from './get_signals_migration_status/get_signals_migration_status_route.mock';
diff --git a/x-pack/plugins/security_solution/server/lib/timeline/schemas/draft_timelines/clean_draft_timelines_schema.ts b/x-pack/plugins/security_solution/common/api/timeline/clean_draft_timelines/clean_draft_timelines_route.ts
similarity index 82%
rename from x-pack/plugins/security_solution/server/lib/timeline/schemas/draft_timelines/clean_draft_timelines_schema.ts
rename to x-pack/plugins/security_solution/common/api/timeline/clean_draft_timelines/clean_draft_timelines_route.ts
index 7dd0de2258a6b..fd967824370ea 100644
--- a/x-pack/plugins/security_solution/server/lib/timeline/schemas/draft_timelines/clean_draft_timelines_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/timeline/clean_draft_timelines/clean_draft_timelines_route.ts
@@ -7,7 +7,7 @@
import * as rt from 'io-ts';
-import { TimelineTypeLiteralRt } from '../../../../../common/types/timeline/api';
+import { TimelineTypeLiteralRt } from '../model/api';
export const cleanDraftTimelineSchema = rt.type({
timelineType: TimelineTypeLiteralRt,
diff --git a/x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/create_timelines_schema.ts b/x-pack/plugins/security_solution/common/api/timeline/create_timelines/create_timelines_route.ts
similarity index 77%
rename from x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/create_timelines_schema.ts
rename to x-pack/plugins/security_solution/common/api/timeline/create_timelines/create_timelines_route.ts
index 800fba1477c41..1911df3941a35 100644
--- a/x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/create_timelines_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/timeline/create_timelines/create_timelines_route.ts
@@ -7,12 +7,13 @@
import * as rt from 'io-ts';
+import type { ResponseTimeline } from '../model/api';
import {
SavedTimelineRuntimeType,
TimelineStatusLiteralRt,
TimelineTypeLiteralRt,
-} from '../../../../../common/types/timeline/api';
-import { unionWithNullType } from '../../../../../common/utility_types';
+} from '../model/api';
+import { unionWithNullType } from '../../../utility_types';
export const createTimelineSchema = rt.intersection([
rt.type({
@@ -27,3 +28,9 @@ export const createTimelineSchema = rt.intersection([
version: unionWithNullType(rt.string),
}),
]);
+
+export interface CreateTimelinesResponse {
+ data: {
+ persistTimeline: ResponseTimeline;
+ };
+}
diff --git a/x-pack/plugins/security_solution/common/api/timeline/delete_note/delete_note_route.ts b/x-pack/plugins/security_solution/common/api/timeline/delete_note/delete_note_route.ts
new file mode 100644
index 0000000000000..af5dbaf394d81
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/timeline/delete_note/delete_note_route.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
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import * as runtimeTypes from 'io-ts';
+import { unionWithNullType } from '../../../utility_types';
+
+export const deleteNoteSchema = runtimeTypes.partial({
+ noteId: unionWithNullType(runtimeTypes.string),
+});
diff --git a/x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/delete_timelines_schema.ts b/x-pack/plugins/security_solution/common/api/timeline/delete_timelines/delete_timelines_route.ts
similarity index 100%
rename from x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/delete_timelines_schema.ts
rename to x-pack/plugins/security_solution/common/api/timeline/delete_timelines/delete_timelines_route.ts
diff --git a/x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/export_timelines_schema.ts b/x-pack/plugins/security_solution/common/api/timeline/export_timelines/export_timelines_route.ts
similarity index 86%
rename from x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/export_timelines_schema.ts
rename to x-pack/plugins/security_solution/common/api/timeline/export_timelines/export_timelines_route.ts
index 778e692b2c0ed..cc391a47e0b9e 100644
--- a/x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/export_timelines_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/timeline/export_timelines/export_timelines_route.ts
@@ -6,7 +6,7 @@
*/
import * as rt from 'io-ts';
-import { unionWithNullType } from '../../../../../common/utility_types';
+import { unionWithNullType } from '../../../utility_types';
export const exportTimelinesQuerySchema = rt.type({
file_name: rt.string,
diff --git a/x-pack/plugins/security_solution/server/lib/timeline/schemas/draft_timelines/get_draft_timelines_schema.ts b/x-pack/plugins/security_solution/common/api/timeline/get_draft_timelines/get_draft_timelines_route.ts
similarity index 82%
rename from x-pack/plugins/security_solution/server/lib/timeline/schemas/draft_timelines/get_draft_timelines_schema.ts
rename to x-pack/plugins/security_solution/common/api/timeline/get_draft_timelines/get_draft_timelines_route.ts
index d995bcedbfb2b..13625715289f6 100644
--- a/x-pack/plugins/security_solution/server/lib/timeline/schemas/draft_timelines/get_draft_timelines_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/timeline/get_draft_timelines/get_draft_timelines_route.ts
@@ -7,7 +7,7 @@
import * as rt from 'io-ts';
-import { TimelineTypeLiteralRt } from '../../../../../common/types/timeline/api';
+import { TimelineTypeLiteralRt } from '../model/api';
export const getDraftTimelineSchema = rt.type({
timelineType: TimelineTypeLiteralRt,
diff --git a/x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/get_timeline_schema.ts b/x-pack/plugins/security_solution/common/api/timeline/get_timeline/get_timeline_route.ts
similarity index 100%
rename from x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/get_timeline_schema.ts
rename to x-pack/plugins/security_solution/common/api/timeline/get_timeline/get_timeline_route.ts
diff --git a/x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/get_timelines_schema.ts b/x-pack/plugins/security_solution/common/api/timeline/get_timelines/get_timelines_route.ts
similarity index 87%
rename from x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/get_timelines_schema.ts
rename to x-pack/plugins/security_solution/common/api/timeline/get_timelines/get_timelines_route.ts
index 3fedcab33d83d..9f35197358aea 100644
--- a/x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/get_timelines_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/timeline/get_timelines/get_timelines_route.ts
@@ -11,8 +11,8 @@ import {
sortFieldTimeline,
TimelineStatusLiteralRt,
TimelineTypeLiteralRt,
-} from '../../../../../common/types/timeline/api';
-import { unionWithNullType } from '../../../../../common/utility_types';
+} from '../model/api';
+import { unionWithNullType } from '../../../utility_types';
const BoolFromString = rt.union([rt.literal('true'), rt.literal('false')]);
diff --git a/x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/import_timelines_schema.ts b/x-pack/plugins/security_solution/common/api/timeline/import_timelines/import_timelines_route.ts
similarity index 78%
rename from x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/import_timelines_schema.ts
rename to x-pack/plugins/security_solution/common/api/timeline/import_timelines/import_timelines_route.ts
index 3858f3886084f..ecd40bab9476b 100644
--- a/x-pack/plugins/security_solution/server/lib/timeline/schemas/timelines/import_timelines_schema.ts
+++ b/x-pack/plugins/security_solution/common/api/timeline/import_timelines/import_timelines_route.ts
@@ -7,11 +7,13 @@
import * as rt from 'io-ts';
-import { SavedTimelineRuntimeType } from '../../../../../common/types/timeline/api';
-import { unionWithNullType } from '../../../../../common/utility_types';
+import { BareNoteSchema, SavedTimelineRuntimeType } from '../model/api';
+import { unionWithNullType } from '../../../utility_types';
-import { eventNotes, globalNotes } from '../notes';
-import { pinnedEventIds } from '../pinned_events';
+import { pinnedEventIds } from '../pinned_events/pinned_events_route';
+
+export const eventNotes = unionWithNullType(rt.array(BareNoteSchema));
+export const globalNotes = unionWithNullType(rt.array(BareNoteSchema));
export const ImportTimelinesSchemaRt = rt.intersection([
SavedTimelineRuntimeType,
diff --git a/x-pack/plugins/security_solution/common/api/timeline/index.ts b/x-pack/plugins/security_solution/common/api/timeline/index.ts
new file mode 100644
index 0000000000000..4a0858b72fea3
--- /dev/null
+++ b/x-pack/plugins/security_solution/common/api/timeline/index.ts
@@ -0,0 +1,21 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './model/api';
+export * from './clean_draft_timelines/clean_draft_timelines_route';
+export * from './get_draft_timelines/get_draft_timelines_route';
+export * from './create_timelines/create_timelines_route';
+export * from './delete_note/delete_note_route';
+export * from './delete_timelines/delete_timelines_route';
+export * from './export_timelines/export_timelines_route';
+export * from './get_timeline/get_timeline_route';
+export * from './get_timelines/get_timelines_route';
+export * from './import_timelines/import_timelines_route';
+export * from './patch_timelines/patch_timelines_schema';
+export * from './persist_favorite/persist_favorite_schema';
+export * from './persist_note/persist_note_route';
+export * from './pinned_events/pinned_events_route';
diff --git a/x-pack/plugins/security_solution/common/types/timeline/api.ts b/x-pack/plugins/security_solution/common/api/timeline/model/api.ts
similarity index 92%
rename from x-pack/plugins/security_solution/common/types/timeline/api.ts
rename to x-pack/plugins/security_solution/common/api/timeline/model/api.ts
index 896405d30ac82..230cf122dcbf6 100644
--- a/x-pack/plugins/security_solution/common/types/timeline/api.ts
+++ b/x-pack/plugins/security_solution/common/api/timeline/model/api.ts
@@ -8,24 +8,61 @@
import * as runtimeTypes from 'io-ts';
import { PositiveInteger } from '@kbn/securitysolution-io-ts-types';
-import { stringEnum, unionWithNullType } from '../../utility_types';
+import { stringEnum, unionWithNullType } from '../../../utility_types';
-import type { Maybe } from '../../search_strategy';
-import { Direction } from '../../search_strategy';
-import type { PinnedEvent } from './pinned_event/api';
-import { PinnedEventRuntimeType } from './pinned_event/api';
+import type { Maybe } from '../../../search_strategy';
+import { Direction } from '../../../search_strategy';
+import type { PinnedEvent } from '../pinned_events/pinned_events_route';
+import { PinnedEventRuntimeType } from '../pinned_events/pinned_events_route';
import {
SavedObjectResolveAliasPurpose,
SavedObjectResolveAliasTargetId,
SavedObjectResolveOutcome,
-} from '../../detection_engine/rule_schema';
-import {
- success,
- success_count as successCount,
-} from '../../detection_engine/schemas/common/schemas';
-import { errorSchema } from '../../detection_engine/schemas/response/error_schema';
-import type { Note } from './note/api';
-import { NoteRuntimeType } from './note/api';
+} from '../../detection_engine/model/rule_schema';
+import { errorSchema, success, success_count as successCount } from '../../detection_engine';
+
+export const BareNoteSchema = runtimeTypes.intersection([
+ runtimeTypes.type({
+ timelineId: unionWithNullType(runtimeTypes.string),
+ }),
+ runtimeTypes.partial({
+ eventId: unionWithNullType(runtimeTypes.string),
+ note: unionWithNullType(runtimeTypes.string),
+ created: unionWithNullType(runtimeTypes.number),
+ createdBy: unionWithNullType(runtimeTypes.string),
+ updated: unionWithNullType(runtimeTypes.number),
+ updatedBy: unionWithNullType(runtimeTypes.string),
+ }),
+]);
+
+export type BareNote = runtimeTypes.TypeOf;
+
+/**
+ * This type represents a note type stored in a saved object that does not include any fields that reference
+ * other saved objects.
+ */
+export type BareNoteWithoutExternalRefs = Omit;
+
+export const NoteRuntimeType = runtimeTypes.intersection([
+ BareNoteSchema,
+ runtimeTypes.type({
+ noteId: runtimeTypes.string,
+ version: runtimeTypes.string,
+ }),
+ runtimeTypes.partial({
+ timelineVersion: unionWithNullType(runtimeTypes.string),
+ }),
+]);
+
+export type Note = runtimeTypes.TypeOf;
+
+export interface ResponseNote {
+ code?: Maybe;
+
+ message?: Maybe;
+
+ note: Note;
+}
/*
* ColumnHeader Types
@@ -636,6 +673,7 @@ export interface ResponseTimeline {
message?: Maybe