From 7cabe6f8e969d0a46aeb81d74a7beda5e6032500 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Tue, 17 Jan 2023 18:04:36 +0200 Subject: [PATCH 01/44] [Cases] Fix name error messages in the creation form (#149030) ## Summary Fixes: https://github.com/elastic/kibana/issues/148041 Screenshot 2023-01-17 at 2 44 27 PM Screenshot 2023-01-17 at 2 45 07 PM ### Checklist Delete any items that are not applicable to this PR. - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- x-pack/plugins/cases/public/common/translations.ts | 2 +- .../cases/public/components/create/form_context.test.tsx | 2 +- x-pack/plugins/cases/public/components/create/schema.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/cases/public/common/translations.ts b/x-pack/plugins/cases/public/common/translations.ts index c738639556055..fdccc41f8e1ac 100644 --- a/x-pack/plugins/cases/public/common/translations.ts +++ b/x-pack/plugins/cases/public/common/translations.ts @@ -166,7 +166,7 @@ export const NO_TAGS = i18n.translate('xpack.cases.caseView.noTags', { }); export const TITLE_REQUIRED = i18n.translate('xpack.cases.createCase.titleFieldRequiredError', { - defaultMessage: 'A title is required.', + defaultMessage: 'A name is required.', }); export const CONFIGURE_CASES_PAGE_TITLE = i18n.translate('xpack.cases.configureCases.headerTitle', { diff --git a/x-pack/plugins/cases/public/components/create/form_context.test.tsx b/x-pack/plugins/cases/public/components/create/form_context.test.tsx index 1f7551b466b8a..37971667da37b 100644 --- a/x-pack/plugins/cases/public/components/create/form_context.test.tsx +++ b/x-pack/plugins/cases/public/components/create/form_context.test.tsx @@ -282,7 +282,7 @@ describe('Create case', () => { await waitFor(() => { expect( - screen.getByText('The length of the title is too long. The maximum length is 160.') + screen.getByText('The length of the name is too long. The maximum length is 160.') ).toBeInTheDocument(); }); diff --git a/x-pack/plugins/cases/public/components/create/schema.tsx b/x-pack/plugins/cases/public/components/create/schema.tsx index f80c4e52945bb..10f414109852d 100644 --- a/x-pack/plugins/cases/public/components/create/schema.tsx +++ b/x-pack/plugins/cases/public/components/create/schema.tsx @@ -58,7 +58,7 @@ export const schema: FormSchema = { { validator: maxLengthField({ length: MAX_TITLE_LENGTH, - message: i18n.MAX_LENGTH_ERROR('title', MAX_TITLE_LENGTH), + message: i18n.MAX_LENGTH_ERROR('name', MAX_TITLE_LENGTH), }), }, ], From 319d9fa42bc333d9d266befebfd361861b6e1f00 Mon Sep 17 00:00:00 2001 From: Julian Gernun <17549662+jcger@users.noreply.github.com> Date: Tue, 17 Jan 2023 17:11:38 +0100 Subject: [PATCH 02/44] [RAM] Alerts table row loading state (#148874) ## Summary Closes [#148786](https://github.com/elastic/kibana/issues/148786) We updated the react context used to save which rows have been selected so now we also save if a previously selected row is in loading state. We will provide a callback that can be called with isLoading true of false for bulk and row actions to represent that a row is currently in loading state. For bulk actions, the callback will be passed by to each item when onClick and for row actions it will be passed by to the renderCustomActionsRow function that the clients can set up on registry ### QA To test this in o11y, you'll have to apply some changes during registry. #### Row actions Currently, o11y uses a function that generates the actions as you can see here `x-pack/plugins/observability/public/config/register_alerts_table_configuration.tsx`: ```ts useActionsColumn: getRowActions(observabilityRuleTypeRegistry, config), ``` In the definition of `getRowActions` in `x-pack/plugins/observability/public/pages/alerts/containers/alerts_table/get_row_actions.tsx` is `renderCustomActionsRow` being returned, with this PR, that function will receive a fourth parameter that can be called. We will name it `updateRowLoadingState` for example, the definition should look like this: ```ts renderCustomActionsRow: ( alert: EcsFieldsResponse, setFlyoutAlert: (data: unknown, id?: string) => void, id?: string, updateRowLoadingState?: (loading: boolean) => void ) => { ``` So now, you'll need to pass this function to the ObservabilityActions component like this ```tsx ``` One last step, open the ObservabilityActions component and add a new actionsMenuItems that looks like this: ```ts { updateRowLoadingState(true); await new Promise((resolve) => setTimeout(resolve, 2000)); updateRowLoadingState(false); }} size="s" > Do something async , ``` Now you should see a new item when clicking on the row actions button called `Do something async` and if you click it, it should show the loading state for 2 seconds until removing it Screenshot 2023-01-16 at 13 13 58 #### Bulk actions: Currently, o11y uses a function that generates the actions as you can see here `x-pack/plugins/observability/public/config/register_alerts_table_configuration.tsx`: ```tsx useBulkActions: useBulkAddToCaseActions, ``` Open the `useBulkAddToCaseActions` definition in `x-pack/plugins/observability/public/hooks/use_alert_bulk_case_actions.ts` and add a new bulkAction like this: ```tsx { label: 'Do something async', key: 'do-something-async', disableOnQuery: true, onClick: async (items, isAllSelected, updateAllLoadingState) => { updateAllLoadingState(true); await new Promise((resolve) => setTimeout(resolve, 2000)); updateAllLoadingState(false); }, }, ``` Now, you should see a new bulk action called `Do something async` and if you click it, it should show the loading state for 2 seconds until removing it on each of the previously selected rows that are part of the bulk action Screenshot 2023-01-16 at 13 21 19 ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../alerts_table/alerts_table.test.tsx | 121 +++++- .../sections/alerts_table/alerts_table.tsx | 23 +- .../alerts_table/alerts_table_state.tsx | 3 +- .../bulk_actions/bulk_actions.test.tsx | 400 +++++++++++------- .../bulk_actions/components/row_cell.tsx | 7 +- .../bulk_actions/components/toolbar.tsx | 23 +- .../alerts_table/bulk_actions/context.ts | 4 +- .../alerts_table/bulk_actions/reducer.ts | 20 +- .../sections/alerts_table/hooks/index.ts | 1 + .../alerts_table/hooks/use_actions_column.ts | 48 +++ .../alerts_table/hooks/use_bulk_actions.ts | 6 + .../toolbar/toolbar_visibility.tsx | 13 +- .../triggers_actions_ui/public/types.ts | 36 +- 13 files changed, 516 insertions(+), 189 deletions(-) create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_actions_column.ts diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.test.tsx index 26bc284f679bc..d283526c9b55b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.test.tsx @@ -4,19 +4,24 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React from 'react'; +import React, { useReducer } from 'react'; -import { render } from '@testing-library/react'; +import { fireEvent, render, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { waitForEuiPopoverOpen } from '@elastic/eui/lib/test/rtl'; import { EcsFieldsResponse } from '@kbn/rule-registry-plugin/common/search_strategy'; import { AlertsTable } from './alerts_table'; -import { AlertsField, AlertsTableProps } from '../../../types'; +import { AlertsField, AlertsTableProps, BulkActionsState, RowSelectionState } from '../../../types'; import { EuiButtonIcon, EuiFlexItem } from '@elastic/eui'; import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; +import { BulkActionsContext } from './bulk_actions/context'; +import { bulkActionsReducer } from './bulk_actions/reducer'; jest.mock('@kbn/data-plugin/public'); +jest.mock('@kbn/kibana-react-plugin/public/ui_settings/use_ui_setting', () => ({ + useUiSetting$: jest.fn((value: string) => ['0,0']), +})); const columns = [ { @@ -73,6 +78,15 @@ describe('AlertsTable', () => { jest.fn().mockImplementation((props) => { return `${props.colIndex}:${props.rowIndex}`; }), + useBulkActions: () => [ + { + label: 'Fake Bulk Action', + key: 'fakeBulkAction', + 'data-test-subj': 'fake-bulk-action', + disableOnQuery: false, + onClick: () => {}, + }, + ], }; const tableProps = { @@ -84,7 +98,6 @@ describe('AlertsTable', () => { pageSize: 1, pageSizeOptions: [1, 10, 20, 50, 100], leadingControlColumns: [], - showCheckboxes: false, showExpandToDetails: true, trailingControlColumns: [], alerts, @@ -99,11 +112,29 @@ describe('AlertsTable', () => { browserFields: {}, }; - const AlertsTableWithLocale: React.FunctionComponent = (props) => ( - - - - ); + const defaultBulkActionsState = { + rowSelection: new Map(), + isAllSelected: false, + areAllVisibleRowsSelected: false, + rowCount: 2, + }; + + const AlertsTableWithLocale: React.FunctionComponent< + AlertsTableProps & { initialBulkActionsState?: BulkActionsState } + > = (props) => { + const initialBulkActionsState = useReducer( + bulkActionsReducer, + props.initialBulkActionsState || defaultBulkActionsState + ); + + return ( + + + + + + ); + }; describe('Alerts table UI', () => { it('should support sorting', async () => { @@ -253,6 +284,78 @@ describe('AlertsTable', () => { expect(queryByTestId('expandColumnHeaderLabel')).toBe(null); expect(queryByTestId('expandColumnCellOpenFlyoutButton')).toBe(null); }); + + describe('row loading state on action', () => { + let mockedFn: jest.Mock; + let customTableProps: AlertsTableProps; + + beforeEach(() => { + mockedFn = jest.fn(); + customTableProps = { + ...tableProps, + pageSize: 2, + alertsTableConfiguration: { + ...alertsTableConfiguration, + useActionsColumn: () => { + return { + renderCustomActionsRow: mockedFn.mockReturnValue( + <> + + {}} + size="s" + data-test-subj="testActionColumn" + /> + + + ), + }; + }, + }, + }; + }); + + it('should show the row loader when callback triggered', async () => { + render(); + fireEvent.click((await screen.findAllByTestId('testActionColumn'))[0]); + + // the callback given to our clients to run when they want to update the loading state + mockedFn.mock.calls[0][3](true); + + expect(await screen.findAllByTestId('row-loader')).toHaveLength(1); + const selectedOptions = await screen.findAllByTestId('dataGridRowCell'); + + // first row, first column + expect(within(selectedOptions[0]).getByLabelText('Loading')).toBeDefined(); + expect(within(selectedOptions[0]).queryByRole('checkbox')).not.toBeInTheDocument(); + + // second row, first column + expect(within(selectedOptions[4]).queryByLabelText('Loading')).not.toBeInTheDocument(); + expect(within(selectedOptions[4]).getByRole('checkbox')).toBeDefined(); + }); + + it('should show the row loader when callback triggered with false', async () => { + const initialBulkActionsState = { + ...defaultBulkActionsState, + rowSelection: new Map([[0, { isLoading: true }]]), + }; + + render( + + ); + fireEvent.click((await screen.findAllByTestId('testActionColumn'))[0]); + + // the callback given to our clients to run when they want to update the loading state + mockedFn.mock.calls[0][3](false); + + expect(screen.queryByTestId('row-loader')).not.toBeInTheDocument(); + }); + }); }); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx index bfc94a19000d6..288ca1f625954 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx @@ -17,7 +17,7 @@ import { EuiDataGridStyle, EuiLoadingContent, } from '@elastic/eui'; -import { useSorting, usePagination, useBulkActions } from './hooks'; +import { useSorting, usePagination, useBulkActions, useActionsColumn } from './hooks'; import { AlertsTableProps } from '../../../types'; import { ALERTS_TABLE_CONTROL_COLUMNS_ACTIONS_LABEL, @@ -28,7 +28,7 @@ import './alerts_table.scss'; import { getToolbarVisibility } from './toolbar'; export const ACTIVE_ROW_CLASS = 'alertsTableActiveRow'; -const DEFAULT_ACTIONS_COLUMNS_WIDTH = 75; + const AlertsFlyout = lazy(() => import('./alerts_flyout')); const GridStyles: EuiDataGridStyle = { border: 'none', @@ -50,16 +50,17 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab } = alertsData; const { sortingColumns, onSort } = useSorting(onSortChange, sortingFields); - const { useActionsColumn = () => ({ renderCustomActionsRow: undefined, width: undefined }) } = - props.alertsTableConfiguration; - const { renderCustomActionsRow, width: actionsColumnWidth = DEFAULT_ACTIONS_COLUMNS_WIDTH } = - useActionsColumn(); + const { renderCustomActionsRow, actionsColumnWidth, getSetIsActionLoadingCallback } = + useActionsColumn({ + options: props.alertsTableConfiguration.useActionsColumn, + }); const { isBulkActionsColumnActive, getBulkActionsLeadingControlColumn, bulkActionsState, bulkActions, + setIsBulkActionsLoading, } = useBulkActions({ alerts, useBulkActionsConfig: props.alertsTableConfiguration.useBulkActions, @@ -112,6 +113,7 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab onResetColumns, browserFields, controls: props.controls, + setIsBulkActionsLoading, }); }, [ bulkActionsState, @@ -125,6 +127,7 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab onResetColumns, browserFields, props.controls, + setIsBulkActionsLoading, ])(); const leadingControlColumns = useMemo(() => { @@ -170,7 +173,12 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab )} {renderCustomActionsRow && alerts[visibleRowIndex] && - renderCustomActionsRow(alerts[visibleRowIndex], handleFlyoutAlert, props.id)} + renderCustomActionsRow( + alerts[visibleRowIndex], + handleFlyoutAlert, + props.id, + getSetIsActionLoadingCallback(visibleRowIndex) + )} ); }, @@ -195,6 +203,7 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab props.showExpandToDetails, renderCustomActionsRow, setFlyoutAlertIndex, + getSetIsActionLoadingCallback, ]); useEffect(() => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx index a35fab760a2f0..a7f6c91a8f5d7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx @@ -31,6 +31,7 @@ import { AlertsTableProps, BulkActionsReducerAction, BulkActionsState, + RowSelectionState, } from '../../../types'; import { ALERTS_TABLE_CONF_ERROR_MESSAGE, ALERTS_TABLE_CONF_ERROR_TITLE } from './translations'; import { TypeRegistry } from '../../type_registry'; @@ -178,7 +179,7 @@ const AlertsTableState = ({ }, []); const initialBulkActionsState = useReducer(bulkActionsReducer, { - rowSelection: new Set(), + rowSelection: new Map(), isAllSelected: false, areAllVisibleRowsSelected: false, rowCount: alerts.length, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/bulk_actions.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/bulk_actions.test.tsx index 43743d09d381a..8eab96f14d23e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/bulk_actions.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/bulk_actions.test.tsx @@ -6,14 +6,18 @@ */ import React, { useReducer } from 'react'; -import { render, within } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { render, screen, within, fireEvent } from '@testing-library/react'; import { waitForEuiPopoverOpen } from '@elastic/eui/lib/test/rtl'; import { EcsFieldsResponse } from '@kbn/rule-registry-plugin/common/search_strategy'; import { BulkActionsContext } from './context'; import { AlertsTable } from '../alerts_table'; -import { AlertsField, AlertsTableProps, BulkActionsState } from '../../../../types'; +import { + AlertsField, + AlertsTableProps, + BulkActionsState, + RowSelectionState, +} from '../../../../types'; import { bulkActionsReducer } from './reducer'; import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; @@ -121,7 +125,7 @@ describe('AlertsTable.BulkActions', () => { }; const defaultBulkActionsState = { - rowSelection: new Set(), + rowSelection: new Map(), isAllSelected: false, areAllVisibleRowsSelected: false, rowCount: 2, @@ -167,32 +171,33 @@ describe('AlertsTable.BulkActions', () => { describe('and click on select all', () => { it('should check that all rows are selected', async () => { - const { getAllByTestId, getByTestId } = render( - - ); - const bulkActionsCells = getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; + render(); + let bulkActionsCells = screen.getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; expect(bulkActionsCells[0].checked).toBeFalsy(); expect(bulkActionsCells[1].checked).toBeFalsy(); - userEvent.click(getByTestId('bulk-actions-header')); + fireEvent.click(screen.getByTestId('bulk-actions-header')); + bulkActionsCells = screen.getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; expect(bulkActionsCells[0].checked).toBeTruthy(); expect(bulkActionsCells[1].checked).toBeTruthy(); }); - it('should show the right amount of alerts selected', () => { + it('should show the right amount of alerts selected', async () => { const props = { ...tablePropsWithBulkActions, initialBulkActionsState: { ...defaultBulkActionsState, areAllVisibleRowsSelected: true, - rowSelection: new Set([0, 1]), + rowSelection: new Map([ + [0, { isLoading: false }], + [1, { isLoading: false }], + ]), }, }; - const { getByTestId } = render(); - const { getByText } = within(getByTestId('selectedShowBulkActionsButton')); - expect(getByText('Selected 2 alerts')).toBeDefined(); + render(); + expect(await screen.findByText('Selected 2 alerts')).toBeDefined(); }); describe('and clicking on a single row', () => { @@ -203,23 +208,29 @@ describe('AlertsTable.BulkActions', () => { initialBulkActionsState: { ...defaultBulkActionsState, areAllVisibleRowsSelected: true, - rowSelection: new Set([0, 1]), + rowSelection: new Map([ + [0, { isLoading: false }], + [1, { isLoading: false }], + ]), }, }; - const { getAllByTestId, getByTestId } = render( - - ); - const bulkActionsCells = getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; - const columnHeader = getByTestId('bulk-actions-header') as HTMLInputElement; - expect(columnHeader.checked).toBeTruthy(); - - userEvent.click(bulkActionsCells[1]); - expect(columnHeader.checked).toBeFalsy(); + render(); + const bulkActionsCells = screen.getAllByTestId( + 'bulk-actions-row-cell' + ) as HTMLInputElement[]; + expect( + (screen.getByTestId('bulk-actions-header') as HTMLInputElement).checked + ).toBeTruthy(); + + fireEvent.click(bulkActionsCells[1]); + expect( + (screen.getByTestId('bulk-actions-header') as HTMLInputElement).checked + ).toBeFalsy(); }); }); describe('and its a page with count of alerts different than page size', () => { - it('should show the right amount of alerts selected', () => { + it('should show the right amount of alerts selected', async () => { const secondPageAlerts = [ { [AlertsField.name]: ['five'], @@ -241,58 +252,64 @@ describe('AlertsTable.BulkActions', () => { initialBulkActionsState: { ...defaultBulkActionsState, areAllVisibleRowsSelected: true, - rowSelection: new Set([0]), + rowSelection: new Map([[0, { isLoading: false }]]), }, }; - const { getByTestId, getAllByTestId } = render( - - ); - const { getByText } = within(getByTestId('selectedShowBulkActionsButton')); - expect(getByText('Selected 1 alert')).toBeDefined(); - expect(getAllByTestId('bulk-actions-row-cell').length).toBe(1); + render(); + + expect(await screen.findByText('Selected 1 alert')).toBeDefined(); + expect((await screen.findAllByTestId('bulk-actions-row-cell')).length).toBe(1); }); }); }); describe('and clicking unselect all', () => { - it('should uncheck all rows', () => { + it('should uncheck all rows', async () => { // state after having already clicked on select all before const props = { ...tablePropsWithBulkActions, initialBulkActionsState: { ...defaultBulkActionsState, areAllVisibleRowsSelected: true, - rowSelection: new Set([0, 1]), + rowSelection: new Map([ + [0, { isLoading: false }], + [1, { isLoading: false }], + ]), }, }; - const { getAllByTestId, getByTestId } = render( - - ); - const bulkActionsCells = getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; - expect(bulkActionsCells[0].checked).toBeTruthy(); - expect(bulkActionsCells[1].checked).toBeTruthy(); - - userEvent.click(getByTestId('bulk-actions-header')); - - expect(bulkActionsCells[0].checked).toBeFalsy(); - expect(bulkActionsCells[1].checked).toBeFalsy(); + render(); + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[0].checked + ).toBeTruthy(); + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[1].checked + ).toBeTruthy(); + + fireEvent.click(await screen.findByTestId('bulk-actions-header')); + + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[0].checked + ).toBeFalsy(); + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[1].checked + ).toBeFalsy(); }); }); describe('and a row is selected', () => { - it('should show the toolbar', () => { - const { queryByTestId, getAllByTestId, getByTestId } = render( - - ); + it('should show the toolbar', async () => { + render(); - expect(queryByTestId('selectedShowBulkActionsButton')).toBeNull(); - expect(queryByTestId('selectAllAlertsButton')).toBeNull(); + expect(screen.queryByTestId('selectedShowBulkActionsButton')).toBeNull(); + expect(screen.queryByTestId('selectAllAlertsButton')).toBeNull(); - const bulkActionsCells = getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; - userEvent.click(bulkActionsCells[0]); + const bulkActionsCells = screen.getAllByTestId( + 'bulk-actions-row-cell' + ) as HTMLInputElement[]; + fireEvent.click(bulkActionsCells[0]); - expect(getByTestId('selectedShowBulkActionsButton')).toBeDefined(); - expect(getByTestId('selectAllAlertsButton')).toBeDefined(); + expect(await screen.findByTestId('selectedShowBulkActionsButton')).toBeDefined(); + expect(await screen.findByTestId('selectAllAlertsButton')).toBeDefined(); }); describe('and the last remaining row is unchecked', () => { @@ -302,7 +319,7 @@ describe('AlertsTable.BulkActions', () => { ...tablePropsWithBulkActions, initialBulkActionsState: { ...defaultBulkActionsState, - rowSelection: new Set([0]), + rowSelection: new Map([[0, { isLoading: false }]]), }, }; const { queryByTestId, getAllByTestId, getByTestId } = render( @@ -313,7 +330,7 @@ describe('AlertsTable.BulkActions', () => { expect(getByTestId('selectAllAlertsButton')).toBeDefined(); const bulkActionsCells = getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; - userEvent.click(bulkActionsCells[0]); + fireEvent.click(bulkActionsCells[0]); expect(queryByTestId('selectAllAlertsButton')).toBeNull(); expect(queryByTestId('selectedShowBulkActionsButton')).toBeNull(); @@ -329,11 +346,10 @@ describe('AlertsTable.BulkActions', () => { ...tablePropsWithBulkActions, initialBulkActionsState: { ...defaultBulkActionsState, - rowSelection: new Set([1]), + rowSelection: new Map([[1, { isLoading: false }]]), }, alertsTableConfiguration: { ...alertsTableConfiguration, - useBulkActions: () => [ { label: 'Fake Bulk Action', @@ -346,84 +362,182 @@ describe('AlertsTable.BulkActions', () => { }, }; - const { getByText, getByTestId } = render( - - ); + render(); - userEvent.click(getByTestId('selectedShowBulkActionsButton')); + fireEvent.click(await screen.findByTestId('selectedShowBulkActionsButton')); await waitForEuiPopoverOpen(); - userEvent.click(getByText('Fake Bulk Action')); - expect(mockedFn.mock.calls[0]).toEqual([ - [ - { + fireEvent.click(await screen.findByText('Fake Bulk Action')); + expect(mockedFn.mock.calls[0][0]).toEqual([ + { + _id: 'alert1', + _index: 'idx1', + data: [ + { + field: 'kibana.alert.rule.name', + value: ['three'], + }, + { + field: 'kibana.alert.rule.uuid', + value: ['uuidtwo'], + }, + ], + ecs: { _id: 'alert1', _index: 'idx1', - data: [ - { - field: 'kibana.alert.rule.name', - value: ['three'], - }, + }, + }, + ]); + expect(mockedFn.mock.calls[0][1]).toEqual(false); + expect(mockedFn.mock.calls[0][2]).toBeDefined(); // it's a callback + }); + + describe('and the callback to represent the loading state is executed', () => { + let mockedFn: jest.Mock; + let props: AlertsTableProps; + + beforeEach(() => { + mockedFn = jest.fn(); + props = { + ...tablePropsWithBulkActions, + alertsTableConfiguration: { + ...alertsTableConfiguration, + useBulkActions: () => [ { - field: 'kibana.alert.rule.uuid', - value: ['uuidtwo'], + label: 'Fake Bulk Action', + key: 'fakeBulkAction', + 'data-test-subj': 'fake-bulk-action', + disableOnQuery: false, + onClick: mockedFn, }, ], - ecs: { - _id: 'alert1', - _index: 'idx1', - }, }, - ], - false, - ]); + }; + }); + + it('should show the loading state on each selected row', async () => { + const initialBulkActionsState = { + ...defaultBulkActionsState, + rowSelection: new Map([[1, { isLoading: false }]]), + }; + render( + + ); + fireEvent.click(await screen.findByTestId('selectedShowBulkActionsButton')); + await waitForEuiPopoverOpen(); + + fireEvent.click(await screen.findByText('Fake Bulk Action')); + + // the callback given to our clients to run when they want to update the loading state + mockedFn.mock.calls[0][2](true); + + expect(await screen.findAllByTestId('row-loader')).toHaveLength(1); + const selectedOptions = await screen.findAllByTestId('dataGridRowCell'); + // first row, first column + expect(within(selectedOptions[0]).queryByLabelText('Loading')).not.toBeInTheDocument(); + expect(within(selectedOptions[0]).getByRole('checkbox')).toBeDefined(); + + // second row, first column + expect(within(selectedOptions[4]).getByLabelText('Loading')).toBeDefined(); + expect(within(selectedOptions[4]).queryByRole('checkbox')).not.toBeInTheDocument(); + }); + + it('should hide the loading state on each selected row', async () => { + const initialBulkActionsState = { + ...defaultBulkActionsState, + rowSelection: new Map([[1, { isLoading: true }]]), + }; + render( + + ); + fireEvent.click(await screen.findByTestId('selectedShowBulkActionsButton')); + await waitForEuiPopoverOpen(); + + fireEvent.click(await screen.findByText('Fake Bulk Action')); + + // the callback given to our clients to run when they want to update the loading state + mockedFn.mock.calls[0][2](false); + + expect(screen.queryByTestId('row-loader')).not.toBeInTheDocument(); + }); }); }); describe('and select all is clicked', () => { - it('should check all the visible rows', () => { + it('should check all the visible rows', async () => { const props = { ...tablePropsWithBulkActions, initialBulkActionsState: { ...defaultBulkActionsState, - rowSelection: new Set([0]), + rowSelection: new Map([[0, { isLoading: false }]]), }, }; - const { getAllByTestId, getByTestId } = render( - - ); - - const bulkActionsCells = getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; - expect(bulkActionsCells[0].checked).toBeTruthy(); - expect(bulkActionsCells[1].checked).toBeFalsy(); - userEvent.click(getByTestId('selectAllAlertsButton')); - expect(bulkActionsCells[0].checked).toBeTruthy(); - expect(bulkActionsCells[1].checked).toBeTruthy(); + render(); + + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[0] + .checked + ).toBeTruthy(); + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[1] + .checked + ).toBeFalsy(); + + fireEvent.click(screen.getByTestId('selectAllAlertsButton')); + + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[0] + .checked + ).toBeTruthy(); + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[1] + .checked + ).toBeTruthy(); }); describe('and clear the selection is clicked', () => { - it('should turn off the toolbar', () => { + it('should turn off the toolbar', async () => { const props = { ...tablePropsWithBulkActions, initialBulkActionsState: { ...defaultBulkActionsState, areAllVisibleRowsSelected: true, isAllSelected: true, - rowSelection: new Set([0, 1]), + rowSelection: new Map([ + [0, { isLoading: false }], + [1, { isLoading: false }], + ]), }, }; - const { getAllByTestId, getByTestId } = render( - - ); - - const bulkActionsCells = getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; - expect(bulkActionsCells[0].checked).toBeTruthy(); - expect(bulkActionsCells[1].checked).toBeTruthy(); - userEvent.click(getByTestId('selectAllAlertsButton')); - expect(bulkActionsCells[0].checked).toBeFalsy(); - expect(bulkActionsCells[1].checked).toBeFalsy(); + render(); + + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[0] + .checked + ).toBeTruthy(); + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[1] + .checked + ).toBeTruthy(); + + fireEvent.click(screen.getByTestId('selectAllAlertsButton')); + + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[0] + .checked + ).toBeFalsy(); + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[1] + .checked + ).toBeFalsy(); }); }); @@ -436,7 +550,10 @@ describe('AlertsTable.BulkActions', () => { ...defaultBulkActionsState, isAllSelected: true, rowCount: 2, - rowSelection: new Set([0, 1]), + rowSelection: new Map([ + [0, { isLoading: false }], + [1, { isLoading: false }], + ]), }, alertsTableConfiguration: { ...alertsTableConfiguration, @@ -456,51 +573,50 @@ describe('AlertsTable.BulkActions', () => { ); - userEvent.click(getByTestId('selectedShowBulkActionsButton')); + fireEvent.click(getByTestId('selectedShowBulkActionsButton')); await waitForEuiPopoverOpen(); - userEvent.click(getByText('Fake Bulk Action')); - expect(mockedFn.mock.calls[0]).toEqual([ - [ - { + fireEvent.click(getByText('Fake Bulk Action')); + expect(mockedFn.mock.calls[0][0]).toEqual([ + { + _id: 'alert0', + _index: 'idx0', + data: [ + { + field: 'kibana.alert.rule.name', + value: ['one'], + }, + { + field: 'kibana.alert.rule.uuid', + value: ['uuidone'], + }, + ], + ecs: { _id: 'alert0', _index: 'idx0', - data: [ - { - field: 'kibana.alert.rule.name', - value: ['one'], - }, - { - field: 'kibana.alert.rule.uuid', - value: ['uuidone'], - }, - ], - ecs: { - _id: 'alert0', - _index: 'idx0', - }, }, - { + }, + { + _id: 'alert1', + _index: 'idx1', + data: [ + { + field: 'kibana.alert.rule.name', + value: ['three'], + }, + { + field: 'kibana.alert.rule.uuid', + value: ['uuidtwo'], + }, + ], + ecs: { _id: 'alert1', _index: 'idx1', - data: [ - { - field: 'kibana.alert.rule.name', - value: ['three'], - }, - { - field: 'kibana.alert.rule.uuid', - value: ['uuidtwo'], - }, - ], - ecs: { - _id: 'alert1', - _index: 'idx1', - }, }, - ], - true, + }, ]); + expect(mockedFn.mock.calls[0][1]).toEqual(true); + expect(mockedFn.mock.calls[0][2]).toBeDefined(); }); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/components/row_cell.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/components/row_cell.tsx index 303141d98b247..75bd47ba1ffad 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/components/row_cell.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/components/row_cell.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiCheckbox } from '@elastic/eui'; +import { EuiCheckbox, EuiLoadingSpinner } from '@elastic/eui'; import React, { ChangeEvent } from 'react'; import { useContext } from 'react'; import { BulkActionsVerbs } from '../../../../../types'; @@ -14,6 +14,11 @@ import { BulkActionsContext } from '../context'; const BulkActionsRowCellComponent = ({ rowIndex }: { rowIndex: number }) => { const [{ rowSelection }, updateSelectedRows] = useContext(BulkActionsContext); const isChecked = rowSelection.has(rowIndex); + const isLoading = isChecked && rowSelection.get(rowIndex)?.isLoading; + + if (isLoading) { + return ; + } return ( void; } // Duplicated just for legacy reasons. Timelines plugin will be removed but @@ -40,9 +41,9 @@ const containerStyles = { display: 'inline-block', position: 'relative' } as con const selectedIdsToTimelineItemMapper = ( alerts: EcsFieldsResponse[], - rowSelection: Set + rowSelection: RowSelection ): TimelineItem[] => { - return Array.from(rowSelection.values()).map((rowIndex: number) => { + return Array.from(rowSelection.keys()).map((rowIndex: number) => { const alert = alerts[rowIndex]; return { _id: alert._id, @@ -61,7 +62,8 @@ const selectedIdsToTimelineItemMapper = ( const useBulkActionsToMenuItemMapper = ( items: BulkActionsConfig[], - alerts: EcsFieldsResponse[] + alerts: EcsFieldsResponse[], + setIsBulkActionsLoading: (loading: boolean) => void ) => { const [{ isAllSelected, rowSelection }] = useContext(BulkActionsContext); @@ -76,25 +78,30 @@ const useBulkActionsToMenuItemMapper = ( disabled={isDisabled} onClick={() => { const selectedAlertIds = selectedIdsToTimelineItemMapper(alerts, rowSelection); - item.onClick(selectedAlertIds, isAllSelected); + item.onClick(selectedAlertIds, isAllSelected, setIsBulkActionsLoading); }} > {isDisabled && item.disabledLabel ? item.disabledLabel : item.label} ); }), - [alerts, isAllSelected, items, rowSelection] + [alerts, isAllSelected, items, rowSelection, setIsBulkActionsLoading] ); return bulkActionsItems; }; -const BulkActionsComponent: React.FC = ({ totalItems, items, alerts }) => { +const BulkActionsComponent: React.FC = ({ + totalItems, + items, + alerts, + setIsBulkActionsLoading, +}) => { const [{ rowSelection, isAllSelected }, updateSelectedRows] = useContext(BulkActionsContext); const [isActionsPopoverOpen, setIsActionsPopoverOpen] = useState(false); const [defaultNumberFormat] = useUiSetting$(DEFAULT_NUMBER_FORMAT); const [showClearSelection, setShowClearSelectiong] = useState(false); - const bulkActionItems = useBulkActionsToMenuItemMapper(items, alerts); + const bulkActionItems = useBulkActionsToMenuItemMapper(items, alerts, setIsBulkActionsLoading); useEffect(() => { setShowClearSelectiong(isAllSelected); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/context.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/context.ts index cafc06a98bb85..85e88815beace 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/context.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/context.ts @@ -6,13 +6,13 @@ */ import { createContext } from 'react'; -import { BulkActionsReducerAction, BulkActionsState } from '../../../../types'; +import { BulkActionsReducerAction, BulkActionsState, RowSelectionState } from '../../../../types'; export const BulkActionsContext = createContext< [BulkActionsState, React.Dispatch] >([ { - rowSelection: new Set(), + rowSelection: new Map(), isAllSelected: false, areAllVisibleRowsSelected: false, rowCount: 0, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/reducer.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/reducer.ts index 4d624dbadfc29..db9c8523fb0af 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/reducer.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/reducer.ts @@ -7,21 +7,22 @@ import { BulkActionsReducerAction, BulkActionsState, BulkActionsVerbs } from '../../../../types'; -const getAllRowsInPage = (rowCount: number) => new Set(Array.from(Array(rowCount).keys())); +const getAllRowsInPage = (rowCount: number) => + new Map(Array.from(Array(rowCount).keys()).map((idx) => [idx, { isLoading: false }])); export const bulkActionsReducer = ( currentState: BulkActionsState, - { action, rowIndex, rowCount }: BulkActionsReducerAction + { action, rowIndex, rowCount, isLoading = false }: BulkActionsReducerAction ): BulkActionsState => { const { rowSelection, rowCount: currentRowCount } = currentState; const nextState = { ...currentState }; if (action === BulkActionsVerbs.add && rowIndex !== undefined) { - const nextRowSelection = new Set(rowSelection); - nextRowSelection.add(rowIndex); + const nextRowSelection = new Map(rowSelection); + nextRowSelection.set(rowIndex, { isLoading }); nextState.rowSelection = nextRowSelection; } else if (action === BulkActionsVerbs.delete && rowIndex !== undefined) { - const nextRowSelection = new Set(rowSelection); + const nextRowSelection = new Map(rowSelection); nextRowSelection.delete(rowIndex); nextState.rowSelection = nextRowSelection; } else if (action === BulkActionsVerbs.selectCurrentPage) { @@ -30,10 +31,17 @@ export const bulkActionsReducer = ( nextState.rowSelection = getAllRowsInPage(currentRowCount); nextState.isAllSelected = true; } else if (action === BulkActionsVerbs.clear) { - nextState.rowSelection = new Set(); + nextState.rowSelection = new Map(); nextState.isAllSelected = false; } else if (action === BulkActionsVerbs.rowCountUpdate && rowCount !== undefined) { nextState.rowCount = rowCount; + } else if (action === BulkActionsVerbs.updateAllLoadingState) { + const nextRowSelection = new Map( + Array.from(rowSelection.keys()).map((idx: number) => [idx, { isLoading }]) + ); + nextState.rowSelection = nextRowSelection; + } else if (action === BulkActionsVerbs.updateRowLoadingState && rowIndex !== undefined) { + nextState.rowSelection.set(rowIndex, { isLoading }); } nextState.areAllVisibleRowsSelected = nextState.rowSelection.size === nextState.rowCount; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/index.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/index.ts index 6c89cec2d59db..3ce3b5ae5cd9a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/index.ts @@ -12,3 +12,4 @@ export type { UseFetchAlerts } from './use_fetch_alerts'; export { useFetchAlerts } from './use_fetch_alerts'; export { DefaultSort } from './constants'; export { useBulkActions } from './use_bulk_actions'; +export { useActionsColumn } from './use_actions_column'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_actions_column.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_actions_column.ts new file mode 100644 index 0000000000000..679fe79b0b036 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_actions_column.ts @@ -0,0 +1,48 @@ +/* + * 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 { useContext } from 'react'; +import { UseActionsColumnRegistry, BulkActionsVerbs } from '../../../../types'; +import { BulkActionsContext } from '../bulk_actions/context'; + +const DEFAULT_ACTIONS_COLUMNS_WIDTH = 75; + +interface UseActionsColumnProps { + options?: UseActionsColumnRegistry; +} + +export const useActionsColumn = ({ options }: UseActionsColumnProps) => { + const [, updateBulkActionsState] = useContext(BulkActionsContext); + + const useUserActionsColumn = options + ? options + : () => ({ + renderCustomActionsRow: undefined, + width: undefined, + }); + + const { renderCustomActionsRow, width: actionsColumnWidth = DEFAULT_ACTIONS_COLUMNS_WIDTH } = + useUserActionsColumn(); + + // we save the rowIndex when creating the function to be used by the clients + // so they don't have to manage it + const getSetIsActionLoadingCallback = + (rowIndex: number) => + (isLoading: boolean = true) => { + updateBulkActionsState({ + action: BulkActionsVerbs.updateRowLoadingState, + rowIndex, + isLoading, + }); + }; + + return { + renderCustomActionsRow, + actionsColumnWidth, + getSetIsActionLoadingCallback, + }; +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts index 0ea19b93e0915..a6cdfe8af2249 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts @@ -28,6 +28,7 @@ export interface UseBulkActions { getBulkActionsLeadingControlColumn: GetLeadingControlColumn; bulkActionsState: BulkActionsState; bulkActions: BulkActionsConfig[]; + setIsBulkActionsLoading: (isLoading: boolean) => void; } export function useBulkActions({ @@ -43,10 +44,15 @@ export function useBulkActions({ updateBulkActionsState({ action: BulkActionsVerbs.rowCountUpdate, rowCount: alerts.length }); }, [alerts, updateBulkActionsState]); + const setIsBulkActionsLoading = (isLoading: boolean = true) => { + updateBulkActionsState({ action: BulkActionsVerbs.updateAllLoadingState, isLoading }); + }; + return { isBulkActionsColumnActive, getBulkActionsLeadingControlColumn, bulkActionsState, bulkActions, + setIsBulkActionsLoading, }; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/toolbar/toolbar_visibility.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/toolbar/toolbar_visibility.tsx index 3c1d259d0b971..da451195c18a6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/toolbar/toolbar_visibility.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/toolbar/toolbar_visibility.tsx @@ -13,7 +13,7 @@ import { EcsFieldsResponse } from '@kbn/rule-registry-plugin/common/search_strat import React, { lazy, Suspense } from 'react'; import { BrowserFields } from '@kbn/rule-registry-plugin/common'; import { AlertsCount } from './components/alerts_count/alerts_count'; -import { BulkActionsConfig } from '../../../../types'; +import { BulkActionsConfig, RowSelection } from '../../../../types'; import { LastUpdatedAt } from './components/last_updated_at'; import { FieldBrowser } from '../../field_browser'; @@ -89,11 +89,12 @@ export const getToolbarVisibility = ({ onToggleColumn, onResetColumns, browserFields, + setIsBulkActionsLoading, controls, }: { bulkActions: BulkActionsConfig[]; alertsCount: number; - rowSelection: Set; + rowSelection: RowSelection; alerts: EcsFieldsResponse[]; isLoading: boolean; updatedAt: number; @@ -101,6 +102,7 @@ export const getToolbarVisibility = ({ onToggleColumn: (columnId: string) => void; onResetColumns: () => void; browserFields: any; + setIsBulkActionsLoading: (isLoading: boolean) => void; controls?: EuiDataGridToolBarAdditionalControlsOptions; }): EuiDataGridToolBarVisibilityOptions => { const selectedRowsCount = rowSelection.size; @@ -128,7 +130,12 @@ export const getToolbarVisibility = ({ <> - + ), diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index 4954c12e252a7..146ffbbd8f420 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -509,9 +509,23 @@ export interface BulkActionsConfig { 'data-test-subj'?: string; disableOnQuery: boolean; disabledLabel?: string; - onClick: (selectedIds: TimelineItem[], isAllSelected: boolean) => void; + onClick: ( + selectedIds: TimelineItem[], + isAllSelected: boolean, + setIsBulkActionsLoading: (isLoading: boolean) => void + ) => void; } +export type UseActionsColumnRegistry = () => { + renderCustomActionsRow: ( + alert: EcsFieldsResponse, + setFlyoutAlert: (data: unknown) => void, + id?: string, + setIsActionLoading?: (isLoading: boolean) => void + ) => JSX.Element; + width?: number; +}; + export type UseBulkActionsRegistry = () => BulkActionsConfig[]; export interface AlertsTableConfigurationRegistry { @@ -525,14 +539,7 @@ export interface AlertsTableConfigurationRegistry { }; sort?: SortCombinations[]; getRenderCellValue?: GetRenderCellValue; - useActionsColumn?: () => { - renderCustomActionsRow: ( - alert: EcsFieldsResponse, - setFlyoutAlert: (data: unknown) => void, - id?: string - ) => JSX.Element; - width?: number; - }; + useActionsColumn?: UseActionsColumnRegistry; useBulkActions?: UseBulkActionsRegistry; usePersistentControls?: () => { right?: ReactNode; @@ -546,21 +553,30 @@ export enum BulkActionsVerbs { selectCurrentPage = 'selectCurrentPage', selectAll = 'selectAll', rowCountUpdate = 'rowCountUpdate', + updateRowLoadingState = 'updateRowLoadingState', + updateAllLoadingState = 'updateAllLoadingState', } export interface BulkActionsReducerAction { action: BulkActionsVerbs; rowIndex?: number; rowCount?: number; + isLoading?: boolean; } export interface BulkActionsState { - rowSelection: Set; + rowSelection: Map; isAllSelected: boolean; areAllVisibleRowsSelected: boolean; rowCount: number; } +export type RowSelection = Map; + +export interface RowSelectionState { + isLoading: boolean; +} + export type RuleStatus = 'enabled' | 'disabled' | 'snoozed'; export enum RRuleFrequency { From 801bb1a51523baecb84a1ef61f5fcd58e658bff6 Mon Sep 17 00:00:00 2001 From: Ying Mao Date: Tue, 17 Jan 2023 11:19:24 -0500 Subject: [PATCH 03/44] [Response Ops][Alerting] Restoring `ActionGroupId` generics (#149040) ## Summary As part of [this PR](https://github.com/elastic/kibana/pull/148751) to encapsulate alert related functionality into a `LegacyAlertsClient`, we removed some generics for `ActionGroupId` because they did not seem necessary. However, they are needed to support scheduling actions, which we add in [this PR](https://github.com/elastic/kibana/pull/147810). This PR is just for restoring the generics for alert related functions. --- .../server/alert/create_alert_factory.ts | 7 +- .../alerts_client/legacy_alerts_client.ts | 39 +++++++---- .../server/lib/determine_alerts_to_return.ts | 8 ++- .../alerting/server/lib/process_alerts.ts | 55 ++++++++++------ .../alerting/server/lib/set_flapping.test.ts | 65 ++++++++++++------- .../alerting/server/lib/set_flapping.ts | 17 +++-- .../server/task_runner/log_alerts.test.ts | 63 +++++++++--------- .../alerting/server/task_runner/log_alerts.ts | 19 ++++-- .../server/task_runner/task_runner.ts | 4 +- 9 files changed, 177 insertions(+), 100 deletions(-) diff --git a/x-pack/plugins/alerting/server/alert/create_alert_factory.ts b/x-pack/plugins/alerting/server/alert/create_alert_factory.ts index c7fea46e37e4b..ff8aacd52f5fe 100644 --- a/x-pack/plugins/alerting/server/alert/create_alert_factory.ts +++ b/x-pack/plugins/alerting/server/alert/create_alert_factory.ts @@ -129,7 +129,12 @@ export function createAlertFactory< return []; } - const { currentRecoveredAlerts } = processAlerts({ + const { currentRecoveredAlerts } = processAlerts< + State, + Context, + ActionGroupIds, + ActionGroupIds + >({ alerts, existingAlerts: originalAlerts, previouslyRecoveredAlerts: {}, diff --git a/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.ts b/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.ts index 95f99a763ad7b..9a8cd78f7fd8f 100644 --- a/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.ts +++ b/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.ts @@ -17,7 +17,12 @@ import { AlertingEventLogger } from '../lib/alerting_event_logger/alerting_event import { RuleRunMetricsStore } from '../lib/rule_run_metrics_store'; import { UntypedNormalizedRuleType } from '../rule_type_registry'; import { logAlerts } from '../task_runner/log_alerts'; -import { AlertInstanceContext, AlertInstanceState, RawAlertInstance } from '../types'; +import { + AlertInstanceContext, + AlertInstanceState, + RawAlertInstance, + WithoutReservedActionGroups, +} from '../types'; interface ConstructorOpts { logger: Logger; @@ -28,19 +33,24 @@ interface ConstructorOpts { export class LegacyAlertsClient< State extends AlertInstanceState, Context extends AlertInstanceContext, - ActionGroupIds extends string + ActionGroupIds extends string, + RecoveryActionGroupId extends string > { private activeAlertsFromPreviousExecution: Record>; private recoveredAlertsFromPreviousExecution: Record>; private alerts: Record>; private processedAlerts: { - new: Record>; - active: Record>; - recovered: Record>; - recoveredCurrent: Record>; + new: Record>; + active: Record>; + recovered: Record>; + recoveredCurrent: Record>; }; - private alertFactory?: AlertFactory; + private alertFactory?: AlertFactory< + State, + Context, + WithoutReservedActionGroups + >; constructor(private readonly options: ConstructorOpts) { this.alerts = {}; this.activeAlertsFromPreviousExecution = {}; @@ -77,7 +87,11 @@ export class LegacyAlertsClient< this.alerts = cloneDeep(this.activeAlertsFromPreviousExecution); - this.alertFactory = createAlertFactory({ + this.alertFactory = createAlertFactory< + State, + Context, + WithoutReservedActionGroups + >({ alerts: this.alerts, logger: this.options.logger, maxAlerts: this.options.maxAlerts, @@ -101,7 +115,7 @@ export class LegacyAlertsClient< activeAlerts: processedAlertsActive, currentRecoveredAlerts: processedAlertsRecoveredCurrent, recoveredAlerts: processedAlertsRecovered, - } = processAlerts({ + } = processAlerts({ alerts: this.alerts, existingAlerts: this.activeAlertsFromPreviousExecution, previouslyRecoveredAlerts: this.recoveredAlertsFromPreviousExecution, @@ -110,7 +124,10 @@ export class LegacyAlertsClient< setFlapping: true, }); - setFlapping(processedAlertsActive, processedAlertsRecovered); + setFlapping( + processedAlertsActive, + processedAlertsRecovered + ); this.processedAlerts.new = processedAlertsNew; this.processedAlerts.active = processedAlertsActive; @@ -139,7 +156,7 @@ export class LegacyAlertsClient< } public getAlertsToSerialize() { - return determineAlertsToReturn( + return determineAlertsToReturn( this.processedAlerts.active, this.processedAlerts.recovered ); diff --git a/x-pack/plugins/alerting/server/lib/determine_alerts_to_return.ts b/x-pack/plugins/alerting/server/lib/determine_alerts_to_return.ts index ff9b5ff0b6353..5916bf91efcc0 100644 --- a/x-pack/plugins/alerting/server/lib/determine_alerts_to_return.ts +++ b/x-pack/plugins/alerting/server/lib/determine_alerts_to_return.ts @@ -12,10 +12,12 @@ import { AlertInstanceState, AlertInstanceContext, RawAlertInstance } from '../t // determines which alerts to return in the state export function determineAlertsToReturn< State extends AlertInstanceState, - Context extends AlertInstanceContext + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string >( - activeAlerts: Record> = {}, - recoveredAlerts: Record> = {} + activeAlerts: Record> = {}, + recoveredAlerts: Record> = {} ): { alertsToReturn: Record; recoveredAlertsToReturn: Record; diff --git a/x-pack/plugins/alerting/server/lib/process_alerts.ts b/x-pack/plugins/alerting/server/lib/process_alerts.ts index 83d375e9b8ac2..40c86dc461ab0 100644 --- a/x-pack/plugins/alerting/server/lib/process_alerts.ts +++ b/x-pack/plugins/alerting/server/lib/process_alerts.ts @@ -25,18 +25,22 @@ interface ProcessAlertsOpts< } interface ProcessAlertsResult< State extends AlertInstanceState, - Context extends AlertInstanceContext + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string > { - newAlerts: Record>; - activeAlerts: Record>; + newAlerts: Record>; + activeAlerts: Record>; // recovered alerts in the current rule run that were previously active - currentRecoveredAlerts: Record>; - recoveredAlerts: Record>; + currentRecoveredAlerts: Record>; + recoveredAlerts: Record>; } export function processAlerts< State extends AlertInstanceState, - Context extends AlertInstanceContext + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string >({ alerts, existingAlerts, @@ -44,7 +48,12 @@ export function processAlerts< hasReachedAlertLimit, alertLimit, setFlapping, -}: ProcessAlertsOpts): ProcessAlertsResult { +}: ProcessAlertsOpts): ProcessAlertsResult< + State, + Context, + ActionGroupIds, + RecoveryActionGroupId +> { return hasReachedAlertLimit ? processAlertsLimitReached( alerts, @@ -58,21 +67,23 @@ export function processAlerts< function processAlertsHelper< State extends AlertInstanceState, - Context extends AlertInstanceContext + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string >( alerts: Record>, existingAlerts: Record>, previouslyRecoveredAlerts: Record>, setFlapping: boolean -): ProcessAlertsResult { +): ProcessAlertsResult { const existingAlertIds = new Set(Object.keys(existingAlerts)); const previouslyRecoveredAlertsIds = new Set(Object.keys(previouslyRecoveredAlerts)); const currentTime = new Date().toISOString(); - const newAlerts: Record> = {}; - const activeAlerts: Record> = {}; - const currentRecoveredAlerts: Record> = {}; - const recoveredAlerts: Record> = {}; + const newAlerts: Record> = {}; + const activeAlerts: Record> = {}; + const currentRecoveredAlerts: Record> = {}; + const recoveredAlerts: Record> = {}; for (const id in alerts) { if (alerts.hasOwnProperty(id)) { @@ -147,14 +158,16 @@ function processAlertsHelper< function processAlertsLimitReached< State extends AlertInstanceState, - Context extends AlertInstanceContext + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string >( alerts: Record>, existingAlerts: Record>, previouslyRecoveredAlerts: Record>, alertLimit: number, setFlapping: boolean -): ProcessAlertsResult { +): ProcessAlertsResult { const existingAlertIds = new Set(Object.keys(existingAlerts)); const previouslyRecoveredAlertsIds = new Set(Object.keys(previouslyRecoveredAlerts)); @@ -164,10 +177,12 @@ function processAlertsLimitReached< // - add any new alerts, up to the max allowed const currentTime = new Date().toISOString(); - const newAlerts: Record> = {}; + const newAlerts: Record> = {}; // all existing alerts stay active - const activeAlerts: Record> = cloneDeep(existingAlerts); + const activeAlerts: Record> = cloneDeep( + existingAlerts + ); // update duration for existing alerts for (const id in activeAlerts) { @@ -231,8 +246,10 @@ function processAlertsLimitReached< export function updateAlertFlappingHistory< State extends AlertInstanceState, - Context extends AlertInstanceContext ->(alert: Alert, state: boolean) { + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string +>(alert: Alert, state: boolean) { const updatedFlappingHistory = updateFlappingHistory(alert.getFlappingHistory() || [], state); alert.setFlappingHistory(updatedFlappingHistory); } diff --git a/x-pack/plugins/alerting/server/lib/set_flapping.test.ts b/x-pack/plugins/alerting/server/lib/set_flapping.test.ts index 93b1cafaca76a..9900d3391861b 100644 --- a/x-pack/plugins/alerting/server/lib/set_flapping.test.ts +++ b/x-pack/plugins/alerting/server/lib/set_flapping.test.ts @@ -7,7 +7,7 @@ import { pick } from 'lodash'; import { Alert } from '../alert'; -import { AlertInstanceState, AlertInstanceContext } from '../../common'; +import { AlertInstanceState, AlertInstanceContext, DefaultActionGroupId } from '../../common'; import { setFlapping, isAlertFlapping } from './set_flapping'; describe('setFlapping', () => { @@ -85,25 +85,34 @@ describe('setFlapping', () => { describe('not currently flapping', () => { test('returns true if the flap count exceeds the threshold', () => { const flappingHistory = [true, true, true, true].concat(new Array(16).fill(false)); - const alert = new Alert('1', { - meta: { flappingHistory }, - }); + const alert = new Alert( + '1', + { + meta: { flappingHistory }, + } + ); expect(isAlertFlapping(alert)).toEqual(true); }); test("returns false the flap count doesn't exceed the threshold", () => { const flappingHistory = [true, true].concat(new Array(20).fill(false)); - const alert = new Alert('1', { - meta: { flappingHistory }, - }); + const alert = new Alert( + '1', + { + meta: { flappingHistory }, + } + ); expect(isAlertFlapping(alert)).toEqual(false); }); test('returns true if not at capacity and the flap count exceeds the threshold', () => { const flappingHistory = new Array(5).fill(true); - const alert = new Alert('1', { - meta: { flappingHistory }, - }); + const alert = new Alert( + '1', + { + meta: { flappingHistory }, + } + ); expect(isAlertFlapping(alert)).toEqual(true); }); }); @@ -111,33 +120,45 @@ describe('setFlapping', () => { describe('currently flapping', () => { test('returns true if at capacity and the flap count exceeds the threshold', () => { const flappingHistory = new Array(16).fill(false).concat([true, true, true, true]); - const alert = new Alert('1', { - meta: { flappingHistory, flapping: true }, - }); + const alert = new Alert( + '1', + { + meta: { flappingHistory, flapping: true }, + } + ); expect(isAlertFlapping(alert)).toEqual(true); }); test("returns true if not at capacity and the flap count doesn't exceed the threshold", () => { const flappingHistory = new Array(16).fill(false); - const alert = new Alert('1', { - meta: { flappingHistory, flapping: true }, - }); + const alert = new Alert( + '1', + { + meta: { flappingHistory, flapping: true }, + } + ); expect(isAlertFlapping(alert)).toEqual(true); }); test('returns true if not at capacity and the flap count exceeds the threshold', () => { const flappingHistory = new Array(10).fill(false).concat([true, true, true, true]); - const alert = new Alert('1', { - meta: { flappingHistory, flapping: true }, - }); + const alert = new Alert( + '1', + { + meta: { flappingHistory, flapping: true }, + } + ); expect(isAlertFlapping(alert)).toEqual(true); }); test("returns false if at capacity and the flap count doesn't exceed the threshold", () => { const flappingHistory = new Array(20).fill(false); - const alert = new Alert('1', { - meta: { flappingHistory, flapping: true }, - }); + const alert = new Alert( + '1', + { + meta: { flappingHistory, flapping: true }, + } + ); expect(isAlertFlapping(alert)).toEqual(false); }); }); diff --git a/x-pack/plugins/alerting/server/lib/set_flapping.ts b/x-pack/plugins/alerting/server/lib/set_flapping.ts index 81e7d0143af6c..2e941cf06e07c 100644 --- a/x-pack/plugins/alerting/server/lib/set_flapping.ts +++ b/x-pack/plugins/alerting/server/lib/set_flapping.ts @@ -10,9 +10,14 @@ import { Alert } from '../alert'; import { AlertInstanceState, AlertInstanceContext } from '../types'; import { isFlapping } from './flapping_utils'; -export function setFlapping( - activeAlerts: Record> = {}, - recoveredAlerts: Record> = {} +export function setFlapping< + State extends AlertInstanceState, + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupIds extends string +>( + activeAlerts: Record> = {}, + recoveredAlerts: Record> = {} ) { for (const id of keys(activeAlerts)) { const alert = activeAlerts[id]; @@ -29,8 +34,10 @@ export function setFlapping(alert: Alert): boolean { + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string +>(alert: Alert): boolean { const flappingHistory: boolean[] = alert.getFlappingHistory() || []; const isCurrentlyFlapping = alert.getFlapping(); return isFlapping(flappingHistory, isCurrentlyFlapping); diff --git a/x-pack/plugins/alerting/server/task_runner/log_alerts.test.ts b/x-pack/plugins/alerting/server/task_runner/log_alerts.test.ts index b903e638e06aa..163cadf1d084b 100644 --- a/x-pack/plugins/alerting/server/task_runner/log_alerts.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/log_alerts.test.ts @@ -9,6 +9,7 @@ import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { Alert } from '../alert'; import { alertingEventLoggerMock } from '../lib/alerting_event_logger/alerting_event_logger.mock'; import { RuleRunMetricsStore } from '../lib/rule_run_metrics_store'; +import { DefaultActionGroupId } from '../types'; import { logAlerts } from './log_alerts'; const logger: ReturnType = loggingSystemMock.createLogger(); @@ -28,8 +29,8 @@ describe('logAlerts', () => { alertingEventLogger, newAlerts: {}, activeAlerts: { - '1': new Alert<{}, {}>('1'), - '2': new Alert<{}, {}>('2'), + '1': new Alert<{}, {}, DefaultActionGroupId>('1'), + '2': new Alert<{}, {}, DefaultActionGroupId>('2'), }, recoveredAlerts: {}, ruleLogPrefix: `test-rule-type-id:123: 'test rule'`, @@ -51,11 +52,11 @@ describe('logAlerts', () => { alertingEventLogger, newAlerts: {}, activeAlerts: { - '1': new Alert<{}, {}>('1'), - '2': new Alert<{}, {}>('2'), + '1': new Alert<{}, {}, DefaultActionGroupId>('1'), + '2': new Alert<{}, {}, DefaultActionGroupId>('2'), }, recoveredAlerts: { - '8': new Alert<{}, {}>('8'), + '8': new Alert<{}, {}, DefaultActionGroupId>('8'), }, ruleLogPrefix: `test-rule-type-id:123: 'test rule'`, ruleRunMetricsStore, @@ -75,8 +76,8 @@ describe('logAlerts', () => { }); test('should correctly debug log recovered alerts if canSetRecoveryContext is true', () => { - const recoveredAlert1 = new Alert<{ value: string }, {}>('8'); - const recoveredAlert2 = new Alert<{ value: string }, {}>('9'); + const recoveredAlert1 = new Alert<{ value: string }, {}, DefaultActionGroupId>('8'); + const recoveredAlert2 = new Alert<{ value: string }, {}, DefaultActionGroupId>('9'); const recoveredAlerts = { '8': recoveredAlert1, '9': recoveredAlert2, @@ -127,18 +128,18 @@ describe('logAlerts', () => { logger, alertingEventLogger, newAlerts: { - '4': new Alert<{}, {}>('4'), + '4': new Alert<{}, {}, DefaultActionGroupId>('4'), }, activeAlerts: { - '1': new Alert<{}, {}>('1'), - '2': new Alert<{}, {}>('2'), - '4': new Alert<{}, {}>('4'), + '1': new Alert<{}, {}, DefaultActionGroupId>('1'), + '2': new Alert<{}, {}, DefaultActionGroupId>('2'), + '4': new Alert<{}, {}, DefaultActionGroupId>('4'), }, recoveredAlerts: { - '7': new Alert<{}, {}>('7'), - '8': new Alert<{}, {}>('8'), - '9': new Alert<{}, {}>('9'), - '10': new Alert<{}, {}>('10'), + '7': new Alert<{}, {}, DefaultActionGroupId>('7'), + '8': new Alert<{}, {}, DefaultActionGroupId>('8'), + '9': new Alert<{}, {}, DefaultActionGroupId>('9'), + '10': new Alert<{}, {}, DefaultActionGroupId>('10'), }, ruleLogPrefix: `test-rule-type-id:123: 'test rule'`, ruleRunMetricsStore, @@ -215,18 +216,18 @@ describe('logAlerts', () => { logger, alertingEventLogger, newAlerts: { - '4': new Alert<{}, {}>('4'), + '4': new Alert<{}, {}, DefaultActionGroupId>('4'), }, activeAlerts: { - '1': new Alert<{}, {}>('1'), - '2': new Alert<{}, {}>('2'), - '4': new Alert<{}, {}>('4'), + '1': new Alert<{}, {}, DefaultActionGroupId>('1'), + '2': new Alert<{}, {}, DefaultActionGroupId>('2'), + '4': new Alert<{}, {}, DefaultActionGroupId>('4'), }, recoveredAlerts: { - '7': new Alert<{}, {}>('7'), - '8': new Alert<{}, {}>('8'), - '9': new Alert<{}, {}>('9'), - '10': new Alert<{}, {}>('10'), + '7': new Alert<{}, {}, DefaultActionGroupId>('7'), + '8': new Alert<{}, {}, DefaultActionGroupId>('8'), + '9': new Alert<{}, {}, DefaultActionGroupId>('9'), + '10': new Alert<{}, {}, DefaultActionGroupId>('10'), }, ruleLogPrefix: `test-rule-type-id:123: 'test rule'`, ruleRunMetricsStore, @@ -246,18 +247,18 @@ describe('logAlerts', () => { logger, alertingEventLogger, newAlerts: { - '4': new Alert<{}, {}>('4'), + '4': new Alert<{}, {}, DefaultActionGroupId>('4'), }, activeAlerts: { - '1': new Alert<{}, {}>('1', { meta: { flapping: true } }), - '2': new Alert<{}, {}>('2'), - '4': new Alert<{}, {}>('4'), + '1': new Alert<{}, {}, DefaultActionGroupId>('1', { meta: { flapping: true } }), + '2': new Alert<{}, {}, DefaultActionGroupId>('2'), + '4': new Alert<{}, {}, DefaultActionGroupId>('4'), }, recoveredAlerts: { - '7': new Alert<{}, {}>('7'), - '8': new Alert<{}, {}>('8', { meta: { flapping: true } }), - '9': new Alert<{}, {}>('9'), - '10': new Alert<{}, {}>('10'), + '7': new Alert<{}, {}, DefaultActionGroupId>('7'), + '8': new Alert<{}, {}, DefaultActionGroupId>('8', { meta: { flapping: true } }), + '9': new Alert<{}, {}, DefaultActionGroupId>('9'), + '10': new Alert<{}, {}, DefaultActionGroupId>('10'), }, ruleLogPrefix: `test-rule-type-id:123: 'test rule'`, ruleRunMetricsStore, diff --git a/x-pack/plugins/alerting/server/task_runner/log_alerts.ts b/x-pack/plugins/alerting/server/task_runner/log_alerts.ts index 4b673b44864dd..7f8f5d93a5d9f 100644 --- a/x-pack/plugins/alerting/server/task_runner/log_alerts.ts +++ b/x-pack/plugins/alerting/server/task_runner/log_alerts.ts @@ -15,20 +15,27 @@ import { RuleRunMetricsStore } from '../lib/rule_run_metrics_store'; export interface LogAlertsParams< State extends AlertInstanceState, - Context extends AlertInstanceContext + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string > { logger: Logger; alertingEventLogger: AlertingEventLogger; - newAlerts: Record>; - activeAlerts: Record>; - recoveredAlerts: Record>; + newAlerts: Record>; + activeAlerts: Record>; + recoveredAlerts: Record>; ruleLogPrefix: string; ruleRunMetricsStore: RuleRunMetricsStore; canSetRecoveryContext: boolean; shouldPersistAlerts: boolean; } -export function logAlerts({ +export function logAlerts< + State extends AlertInstanceState, + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string +>({ logger, alertingEventLogger, newAlerts, @@ -38,7 +45,7 @@ export function logAlerts) { +}: LogAlertsParams) { const newAlertIds = Object.keys(newAlerts); const activeAlertIds = Object.keys(activeAlerts); const recoveredAlertIds = Object.keys(recoveredAlerts); diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts index 27977dd3bf6f5..e88922f51ddb1 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts @@ -44,7 +44,6 @@ import { RuleTypeParams, RuleTypeState, parseDuration, - WithoutReservedActionGroups, } from '../../common'; import { NormalizedRuleType, UntypedNormalizedRuleType } from '../rule_type_registry'; import { getEsErrorMessage } from '../lib/errors'; @@ -114,7 +113,8 @@ export class TaskRunner< private legacyAlertsClient: LegacyAlertsClient< State, Context, - WithoutReservedActionGroups + ActionGroupIds, + RecoveryActionGroupId >; constructor( From 8836e784601dcb64b35be704cfec8ba3718de52c Mon Sep 17 00:00:00 2001 From: Saarika Bhasi <55930906+saarikabhasi@users.noreply.github.com> Date: Tue, 17 Jan 2023 11:19:40 -0500 Subject: [PATCH 04/44] [Enterprise Search] Engine List - Delete engine (#148771) ## Summary Engines List page: * Delete feature * Updated Last updated date column #### Screenshots Screen Shot 2023-01-11 at 9 24 30 PM Screen Shot 2023-01-11 at 9 24 44 PM ### Checklist Delete any items that are not applicable to this PR. - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../engines/delete_engines_api_logic.test.ts | 31 +++ .../api/engines/delete_engines_api_logic.ts | 44 ++++ .../components/tables/engines_table.tsx | 31 ++- .../engines/delete_engine_modal.tsx | 60 +++++ .../engines/engine_list_logic.test.ts | 80 +++++-- .../components/engines/engines_list.tsx | 221 ++++++++++-------- .../components/engines/engines_list_logic.ts | 82 ++++++- .../enterprise_search_content/routes.ts | 1 + .../routes/enterprise_search/engines.ts | 5 +- 9 files changed, 422 insertions(+), 133 deletions(-) create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/engines/delete_engines_api_logic.test.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/engines/delete_engines_api_logic.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/delete_engine_modal.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/engines/delete_engines_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/engines/delete_engines_api_logic.test.ts new file mode 100644 index 0000000000000..d7b322bdcef3f --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/engines/delete_engines_api_logic.test.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. + */ + +import { mockHttpValues } from '../../../__mocks__/kea_logic'; + +import { nextTick } from '@kbn/test-jest-helpers'; + +import { deleteEngine } from './delete_engines_api_logic'; + +describe('deleteEngineApiLogic', () => { + const { http } = mockHttpValues; + beforeEach(() => { + jest.clearAllMocks(); + }); + describe('deleteEngine', () => { + it('calls correct api', async () => { + const promise = Promise.resolve(); + http.post.mockReturnValue(promise); + const result = deleteEngine({ engineName: 'deleteEngineName' }); + await nextTick(); + expect(http.delete).toHaveBeenCalledWith( + '/internal/enterprise_search/engines/deleteEngineName' + ); + await expect(result).resolves; + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/engines/delete_engines_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/engines/delete_engines_api_logic.ts new file mode 100644 index 0000000000000..c99e8c641c2db --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/engines/delete_engines_api_logic.ts @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +import { Actions, createApiLogic } from '../../../shared/api_logic/create_api_logic'; +import { HttpLogic } from '../../../shared/http'; + +export interface DeleteEnginesApiLogicArguments { + engineName: string; +} +export interface DeleteEnginesApiLogicResponse { + engineName: string; +} + +export const deleteEngine = async ({ + engineName, +}: DeleteEnginesApiLogicArguments): Promise => { + const route = `/internal/enterprise_search/engines/${engineName}`; + await HttpLogic.values.http.delete(route); + return { engineName }; +}; +export const DeleteEngineAPILogic = createApiLogic( + ['content', 'delete_engine_api_logic'], + deleteEngine, + { + showSuccessFlashFn: ({ engineName }) => + i18n.translate('xpack.enterpriseSearch.content.engineList.deleteEngine.successToast.title', { + defaultMessage: '{engineName} has been deleted', + values: { + engineName, + }, + }), + } +); + +export type DeleteEnginesApiLogicActions = Actions< + DeleteEnginesApiLogicArguments, + DeleteEnginesApiLogicResponse +>; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/components/tables/engines_table.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/components/tables/engines_table.tsx index b06264e85012a..6bdb73a074d4b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/components/tables/engines_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/components/tables/engines_table.tsx @@ -14,13 +14,15 @@ import { CriteriaWithPagination, EuiBasicTable, EuiBasicTableColumn } from '@ela import { i18n } from '@kbn/i18n'; import { EnterpriseSearchEngine } from '../../../../../../../common/types/engines'; +import { MANAGE_BUTTON_LABEL } from '../../../../../shared/constants'; -import { DELETE_BUTTON_LABEL, MANAGE_BUTTON_LABEL } from '../../../../../shared/constants'; import { generateEncodedPath } from '../../../../../shared/encode_path_params'; +import { FormattedDateTime } from '../../../../../shared/formatted_date_time'; import { KibanaLogic } from '../../../../../shared/kibana'; import { EuiLinkTo } from '../../../../../shared/react_router_helpers'; import { ENGINE_PATH } from '../../../../routes'; + import { convertMetaToPagination, Meta } from '../../types'; // add health status @@ -30,12 +32,14 @@ interface EnginesListTableProps { loading: boolean; meta: Meta; onChange: (criteria: CriteriaWithPagination) => void; + onDelete: (engine: EnterpriseSearchEngine) => void; } export const EnginesListTable: React.FC = ({ enginesList, - meta, isLoading, + meta, onChange, + onDelete, }) => { const { navigateToUrl } = useValues(KibanaLogic); const columns: Array> = [ @@ -52,6 +56,7 @@ export const EnginesListTable: React.FC = ({ render: (name: string) => ( {name} @@ -61,11 +66,12 @@ export const EnginesListTable: React.FC = ({ width: '30%', }, { - field: 'last_updated', + field: 'updated', name: i18n.translate('xpack.enterpriseSearch.content.enginesList.table.column.lastUpdated', { defaultMessage: 'Last updated', }), dataType: 'string', + render: (dateString: string) => , }, { field: 'indices.length', @@ -83,9 +89,9 @@ export const EnginesListTable: React.FC = ({ { name: MANAGE_BUTTON_LABEL, description: i18n.translate( - 'xpack.enterpriseSearch.content.enginesList.table.column.action.manage.buttonDescription', + 'xpack.enterpriseSearch.content.enginesList.table.column.actions.view.buttonDescription', { - defaultMessage: 'Manage this engine', + defaultMessage: 'View this engine', } ), type: 'icon', @@ -98,7 +104,7 @@ export const EnginesListTable: React.FC = ({ ), }, { - name: DELETE_BUTTON_LABEL, + color: 'danger', description: i18n.translate( 'xpack.enterpriseSearch.content.enginesList.table.column.action.delete.buttonDescription', { @@ -107,8 +113,17 @@ export const EnginesListTable: React.FC = ({ ), type: 'icon', icon: 'trash', - color: 'danger', - onClick: () => {}, + isPrimary: false, + name: () => + i18n.translate( + 'xpack.enterpriseSearch.content.engineList.table.column.actions.deleteEngineLabel', + { + defaultMessage: 'Delete this engine', + } + ), + onClick: (engine) => { + onDelete(engine); + }, }, ], }, diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/delete_engine_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/delete_engine_modal.tsx new file mode 100644 index 0000000000000..16dfdf50a7470 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/delete_engine_modal.tsx @@ -0,0 +1,60 @@ +/* + * 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 React from 'react'; + +import { useActions, useValues } from 'kea'; + +import { EuiConfirmModal } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { CANCEL_BUTTON_LABEL } from '../../../shared/constants'; + +import { EnginesListLogic } from './engines_list_logic'; + +export const DeleteEngineModal: React.FC = () => { + const { closeDeleteEngineModal, deleteEngine } = useActions(EnginesListLogic); + const { + deleteModalEngineName: engineName, + isDeleteModalVisible, + isDeleteLoading, + } = useValues(EnginesListLogic); + + if (isDeleteModalVisible) { + return ( + { + deleteEngine({ engineName }); + }} + cancelButtonText={CANCEL_BUTTON_LABEL} + confirmButtonText={i18n.translate( + 'xpack.enterpriseSearch.content.engineList.deleteEngineModal.confirmButton.title', + { + defaultMessage: 'Yes, delete this engine ', + } + )} + buttonColor="danger" + isLoading={isDeleteLoading} + > +

+ {i18n.translate( + 'xpack.enterpriseSearch.content.engineList.deleteEngineModal.delete.description', + { + defaultMessage: + 'Deleting your engine is not a reversible action. Your indices will not be affected. ', + } + )} +

+
+ ); + } else { + return <>; + } +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engine_list_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engine_list_logic.test.ts index 3dc99d5717845..a88203f81ea9e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engine_list_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engine_list_logic.test.ts @@ -19,13 +19,19 @@ import { DEFAULT_META } from './types'; const DEFAULT_VALUES = { data: undefined, - results: [], + deleteModalEngine: null, + deleteModalEngineName: '', + deleteStatus: Status.IDLE, + isDeleteLoading: false, + isDeleteModalVisible: false, + isLoading: false, meta: DEFAULT_META, parameters: { meta: DEFAULT_META }, + results: [], status: Status.IDLE, }; -// sample engines list +// may need to call mock engines response when ready const results: EnterpriseSearchEngine[] = [ { @@ -33,24 +39,18 @@ const results: EnterpriseSearchEngine[] = [ indices: ['index-18', 'index-23'], name: 'engine-name-1', updated: '1999-12-31T23:59:59Z', - // last_updated: '21 March 2021', - // document_count: 18, }, { created: '1999-12-31T23:59:59Z', indices: ['index-180', 'index-230', 'index-8', 'index-2'], name: 'engine-name-2', updated: '1999-12-31T23:59:59Z', - // last_updated: '10 Jul 2018', - // document_count: 10, }, { created: '1999-12-31T23:59:59Z', indices: ['index-2', 'index-3'], name: 'engine-name-3', updated: '1999-12-31T23:59:59Z', - // last_updated: '21 December 2022', - // document_count: 8, }, ]; @@ -88,6 +88,24 @@ describe('EnginesListLogic', () => { // }); }); }); + describe('closeDeleteEngineModal', () => { + it('set isDeleteModalVisible to false and engineName to empty string', () => { + EnginesListLogic.actions.openDeleteEngineModal(results[0]); + EnginesListLogic.actions.closeDeleteEngineModal(); + expect(EnginesListLogic.values).toEqual(DEFAULT_VALUES); + }); + }); + describe('openDeleteEngineModal', () => { + it('set deleteModalEngineName and set isDeleteModalVisible to true', () => { + EnginesListLogic.actions.openDeleteEngineModal(results[0]); + expect(EnginesListLogic.values).toEqual({ + ...DEFAULT_VALUES, + deleteModalEngine: results[0], + deleteModalEngineName: 'engine-name-1', + isDeleteModalVisible: true, + }); + }); + }); }); describe('reducers', () => { describe('meta', () => { @@ -120,14 +138,50 @@ describe('EnginesListLogic', () => { }); }); }); + describe('request to delete Engine', () => { + it('should set isDeleteLoading to true on delete engine request', () => { + EnginesListLogic.actions.deleteEngine({ engineName: results[0].name }); + EnginesListLogic.actions.deleteError({} as HttpError); + expect(EnginesListLogic.values).toEqual({ + ...DEFAULT_VALUES, + deleteStatus: Status.ERROR, + isDeleteLoading: false, + }); + }); + it('should set isDeleteLoading to false on delete apiError', () => { + EnginesListLogic.actions.deleteEngine({ engineName: results[0].name }); + EnginesListLogic.actions.deleteError({} as HttpError); + expect(EnginesListLogic.values).toEqual({ + ...DEFAULT_VALUES, + deleteStatus: Status.ERROR, + isDeleteLoading: false, + }); + }); + it('should set isDeleteLoading to false on delete apiSuccess', () => { + EnginesListLogic.actions.deleteEngine({ engineName: results[0].name }); + EnginesListLogic.actions.deleteSuccess({ engineName: results[0].name }); + expect(EnginesListLogic.values).toEqual({ + ...DEFAULT_VALUES, + deleteStatus: Status.SUCCESS, + isDeleteLoading: false, + isLoading: true, + status: Status.LOADING, // fetchEngine api status + }); + }); + }); }); describe('listeners', () => { - it('call flashAPIErrors on apiError', () => { - EnginesListLogic.actions.apiError({} as HttpError); - expect(mockFlashMessageHelpers.flashAPIErrors).toHaveBeenCalledTimes(1); - expect(mockFlashMessageHelpers.flashAPIErrors).toHaveBeenCalledWith({}); - }); + it('calls flashSuccessToast, closeDeleteEngineModal and fetchEngines on deleteSuccess', () => { + EnginesListLogic.actions.fetchEngines = jest.fn(); + EnginesListLogic.actions.closeDeleteEngineModal = jest.fn(); + EnginesListLogic.actions.deleteSuccess({ engineName: results[0].name }); + expect(mockFlashMessageHelpers.flashSuccessToast).toHaveBeenCalledTimes(1); + expect(EnginesListLogic.actions.fetchEngines).toHaveBeenCalledWith( + EnginesListLogic.values.parameters + ); + expect(EnginesListLogic.actions.closeDeleteEngineModal).toHaveBeenCalled(); + }); it('call makeRequest on fetchEngines', async () => { jest.useFakeTimers({ legacyFakeTimers: true }); EnginesListLogic.actions.makeRequest = jest.fn(); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list.tsx index 6c7540cd3f92d..51eb674764066 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list.tsx @@ -17,13 +17,15 @@ import { FormattedMessage, FormattedNumber } from '@kbn/i18n-react'; import { DataPanel } from '../../../shared/data_panel/data_panel'; import { handlePageChange } from '../../../shared/table_pagination'; + import { EnterpriseSearchContentPageTemplate } from '../layout/page_template'; import { EnginesListTable } from './components/tables/engines_table'; +import { DeleteEngineModal } from './delete_engine_modal'; import { EnginesListLogic } from './engines_list_logic'; export const EnginesList: React.FC = () => { - const { fetchEngines, onPaginate } = useActions(EnginesListLogic); + const { fetchEngines, onPaginate, openDeleteEngineModal } = useActions(EnginesListLogic); const { meta, results } = useValues(EnginesListLogic); const [searchQuery, setSearchValue] = useState(''); @@ -35,106 +37,127 @@ export const EnginesList: React.FC = () => { }, [meta.from, meta.size, searchQuery]); return ( - - {i18n.translate('xpack.enterpriseSearch.content.engines.createEngineButtonLabel', { - defaultMessage: 'Create engine', - })} - , - ], - }} - pageViewTelemetry="Engines" - isLoading={false} - > - - {i18n.translate('xpack.enterpriseSearch.content.engines.description', { - defaultMessage: - 'Engines allow you to query indexed data with a complete set of relevance, analytics and personalization tools. To learn more about how engines work in Enterprise search ', - })} - - - {i18n.translate('xpack.enterpriseSearch.content.engines.documentation', { - defaultMessage: 'explore our Engines documentation', - })} - - - -
- + + + {i18n.translate('xpack.enterpriseSearch.content.engines.createEngineButtonLabel', { + defaultMessage: 'Create engine', + })} + , + ], + }} + pageViewTelemetry="Engines" + isLoading={false} + > + + + {' '} + {/* TODO: navigate to documentation url */}{' '} + {i18n.translate('xpack.enterpriseSearch.content.engines.documentation', { + defaultMessage: 'explore our Engines documentation', + })} + + ), + }} + /> + + +
+ { + setSearchValue(event.currentTarget.value); + }} + /> +
+ + + {i18n.translate('xpack.enterpriseSearch.content.engines.searchPlaceholder.description', { + defaultMessage: 'Locate an engine via name or indices', })} - fullWidth - onChange={(event) => { - setSearchValue(event.currentTarget.value); - }} - /> -
- - - {i18n.translate('xpack.enterpriseSearch.content.engines.searchPlaceholder.description', { - defaultMessage: 'Locate an engine via name or indices', - })} - + - - - - - - ), - size: ( - - - - ), - total: , - }} - /> - - - {i18n.translate('xpack.enterpriseSearch.content.engines.title', { - defaultMessage: 'Engines', - })} - - } - > - - + + + + + + ), + size: ( + + + + ), + total: , + }} + /> + + + {i18n.translate('xpack.enterpriseSearch.content.engines.title', { + defaultMessage: 'Engines', + })} + + } + > + + - -
- + +
+ + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list_logic.ts index 10f13265c4ea5..4d58ff95bc15a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list_logic.ts @@ -7,6 +7,8 @@ import { kea, MakeLogicType } from 'kea'; +import { Status } from '../../../../../common/types/api'; + import { EnterpriseSearchEngine, EnterpriseSearchEnginesResponse, @@ -14,6 +16,11 @@ import { import { Actions } from '../../../shared/api_logic/create_api_logic'; +import { + DeleteEngineAPILogic, + DeleteEnginesApiLogicActions, +} from '../../api/engines/delete_engines_api_logic'; + import { EnginesListAPIArguments, FetchEnginesAPILogic, @@ -25,40 +32,73 @@ type EnginesListActions = Pick< Actions, 'apiError' | 'apiSuccess' | 'makeRequest' > & { + closeDeleteEngineModal(): void; + deleteError: DeleteEnginesApiLogicActions['apiError']; + deleteEngine: DeleteEnginesApiLogicActions['makeRequest']; + deleteSuccess: DeleteEnginesApiLogicActions['apiSuccess']; + fetchEngines({ meta, searchQuery }: { meta: Meta; searchQuery?: string }): { meta: Meta; searchQuery?: string; }; + + openDeleteEngineModal: (engine: EnterpriseSearchEngine) => { engine: EnterpriseSearchEngine }; onPaginate(pageNumber: number): { pageNumber: number }; }; interface EngineListValues { data: typeof FetchEnginesAPILogic.values.data; + deleteModalEngine: EnterpriseSearchEngine | null; + deleteModalEngineName: string; + deleteStatus: typeof DeleteEngineAPILogic.values.status; + isLoading: boolean; + isDeleteLoading: boolean; + isDeleteModalVisible: boolean; meta: Meta; - results: EnterpriseSearchEngine[]; // stores engine list value from data parameters: { meta: Meta; searchQuery?: string }; // Added this variable to store to the search Query value as well + results: EnterpriseSearchEngine[]; // stores engine list value from data status: typeof FetchEnginesAPILogic.values.status; } export const EnginesListLogic = kea>({ + connect: { + actions: [ + FetchEnginesAPILogic, + ['makeRequest', 'apiSuccess', 'apiError'], + DeleteEngineAPILogic, + ['apiSuccess as deleteSuccess', 'makeRequest as deleteEngine', 'apiError as deleteError'], + ], + values: [ + FetchEnginesAPILogic, + ['data', 'status'], + DeleteEngineAPILogic, + ['status as deleteStatus'], + ], + }, actions: { + closeDeleteEngineModal: true, fetchEngines: ({ meta, searchQuery }) => ({ meta, searchQuery, }), - + openDeleteEngineModal: (engine) => ({ engine }), onPaginate: (pageNumber) => ({ pageNumber }), }, - connect: { - actions: [FetchEnginesAPILogic, ['makeRequest', 'apiSuccess', 'apiError']], - values: [FetchEnginesAPILogic, ['data', 'status']], - }, - listeners: ({ actions }) => ({ - fetchEngines: async (input) => { - actions.makeRequest(input); - }, - }), path: ['enterprise_search', 'content', 'engine_list_logic'], reducers: ({}) => ({ + deleteModalEngine: [ + null, + { + closeDeleteEngineModal: () => null, + openDeleteEngineModal: (_, { engine }) => engine, + }, + ], + isDeleteModalVisible: [ + false, + { + closeDeleteEngineModal: () => false, + openDeleteEngineModal: () => true, + }, + ], parameters: [ { meta: DEFAULT_META }, { @@ -73,7 +113,25 @@ export const EnginesListLogic = kea ({ - meta: [() => [selectors.parameters], (parameters) => parameters.meta], + deleteModalEngineName: [() => [selectors.deleteModalEngine], (engine) => engine?.name ?? ''], + isDeleteLoading: [ + () => [selectors.deleteStatus], + (status: EngineListValues['deleteStatus']) => [Status.LOADING].includes(status), + ], + isLoading: [ + () => [selectors.status], + (status: EngineListValues['status']) => [Status.LOADING].includes(status), + ], results: [() => [selectors.data], (data) => data?.results ?? []], + meta: [() => [selectors.parameters], (parameters) => parameters.meta], + }), + listeners: ({ actions, values }) => ({ + deleteSuccess: () => { + actions.closeDeleteEngineModal(); + actions.fetchEngines(values.parameters); + }, + fetchEngines: async (input) => { + actions.makeRequest(input); + }, }), }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts index 07c9a886fa597..4185addb31445 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts @@ -25,6 +25,7 @@ export const OLD_SEARCH_INDEX_CRAWLER_DOMAIN_DETAIL_PATH = `${SEARCH_INDEX_PATH} export const SEARCH_INDEX_SELECT_CONNECTOR_PATH = `${SEARCH_INDEX_PATH}/select_connector`; export const ENGINES_PATH = `${ROOT_PATH}engines`; + export const ENGINE_CREATION_PATH = `${ENGINES_PATH}/new`; export const ENGINE_PATH = `${ENGINES_PATH}/:engineName`; export const ENGINE_TAB_PATH = `${ENGINE_PATH}/:tabId`; diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/engines.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/engines.ts index cc3337147934b..c4e216f52183d 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/engines.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/engines.ts @@ -62,6 +62,9 @@ export function registerEnginesRoutes({ }), }, }, - enterpriseSearchRequestHandler.createRequest({ path: '/api/engines/:engine_name' }) + enterpriseSearchRequestHandler.createRequest({ + path: '/api/engines/:engine_name', + hasJsonResponse: false, + }) ); } From 9e837b80dca0d93c3da9da98a1d913c7a0a882ca Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Tue, 17 Jan 2023 08:20:51 -0800 Subject: [PATCH 05/44] [DOCS] Add 401 responses to case API specifications (#148857) --- .../cases/case-apis-passthru.asciidoc | 94 +++++++ .../plugins/cases/docs/openapi/bundled.json | 237 ++++++++++++++++++ .../plugins/cases/docs/openapi/bundled.yaml | 144 +++++++++++ .../components/schemas/4xx_response.yaml | 11 + .../openapi/paths/s@{spaceid}@api@cases.yaml | 18 ++ .../paths/s@{spaceid}@api@cases@_find.yaml | 6 + ...@{spaceid}@api@cases@alerts@{alertid}.yaml | 8 +- .../s@{spaceid}@api@cases@configure.yaml | 13 +- ...@api@cases@configure@connectors@_find.yaml | 6 + ...api@cases@configure@{configurationid}.yaml | 6 + .../s@{spaceid}@api@cases@reporters.yaml | 6 + .../paths/s@{spaceid}@api@cases@status.yaml | 6 + .../paths/s@{spaceid}@api@cases@tags.yaml | 7 +- .../paths/s@{spaceid}@api@cases@{caseid}.yaml | 6 + ...s@{spaceid}@api@cases@{caseid}@alerts.yaml | 6 + ...{spaceid}@api@cases@{caseid}@comments.yaml | 26 +- ...i@cases@{caseid}@comments@{commentid}.yaml | 13 +- ...caseid}@connector@{connectorid}@_push.yaml | 6 + ...ceid}@api@cases@{caseid}@user_actions.yaml | 6 + 19 files changed, 619 insertions(+), 6 deletions(-) create mode 100644 x-pack/plugins/cases/docs/openapi/components/schemas/4xx_response.yaml diff --git a/docs/api-generated/cases/case-apis-passthru.asciidoc b/docs/api-generated/cases/case-apis-passthru.asciidoc index 80e8c7eb9cac7..b95159d606ab1 100644 --- a/docs/api-generated/cases/case-apis-passthru.asciidoc +++ b/docs/api-generated/cases/case-apis-passthru.asciidoc @@ -160,6 +160,9 @@ Any modifications made to this file will be overwritten.

200

Indicates a successful call. case_response_properties +

401

+ Authorization information is missing or invalid. + 4xx_response






















@@ -1878,6 +1962,7 @@ Any modifications made to this file will be overwritten.

Table of Contents

    +
  1. 4xx_response - Unsuccessful cases API response
  2. Case_response_properties_for_comments_inner -
  3. Case_response_properties_for_connectors - Case response properties for connectors
  4. action_types -
  5. @@ -1964,6 +2049,15 @@ Any modifications made to this file will be overwritten.
  6. user_comment_response_properties - Case response properties for user comments
+
+

4xx_response - Unsuccessful cases API response Up

+
+
+
error (optional)
+
message (optional)
+
statusCode (optional)
+
+

Case_response_properties_for_comments_inner - Up

diff --git a/x-pack/plugins/cases/docs/openapi/bundled.json b/x-pack/plugins/cases/docs/openapi/bundled.json index 226d5578e8521..3fad9872c07bf 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.json +++ b/x-pack/plugins/cases/docs/openapi/bundled.json @@ -71,6 +71,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -107,6 +117,16 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -162,6 +182,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -419,6 +449,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -482,6 +522,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -649,6 +699,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -882,6 +942,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1104,6 +1174,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1184,6 +1264,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1253,6 +1343,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1310,6 +1410,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1373,6 +1483,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1428,6 +1548,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1477,6 +1607,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1540,6 +1680,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1569,6 +1719,16 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1625,6 +1785,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1659,6 +1829,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1698,6 +1878,16 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1746,6 +1936,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1807,6 +2007,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1856,6 +2066,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -3008,6 +3228,23 @@ } } }, + "4xx_response": { + "type": "object", + "title": "Unsuccessful cases API response", + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "example": 401 + } + } + }, "update_case_request": { "title": "Update case request", "description": "The update case API request body varies depending on the type of connector.", diff --git a/x-pack/plugins/cases/docs/openapi/bundled.yaml b/x-pack/plugins/cases/docs/openapi/bundled.yaml index e01bf8c4fea10..129bf13a79b48 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.yaml +++ b/x-pack/plugins/cases/docs/openapi/bundled.yaml @@ -45,6 +45,12 @@ paths: examples: createCaseResponse: $ref: '#/components/examples/create_case_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 delete: @@ -67,6 +73,12 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 patch: @@ -99,6 +111,12 @@ paths: examples: updateCaseResponse: $ref: '#/components/examples/update_case_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -257,6 +275,12 @@ paths: examples: findCaseResponse: $ref: '#/components/examples/find_case_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -293,6 +317,12 @@ paths: example: - id: 06116b80-e1c3-11ec-be9b-9b1838238ee6 title: security_case + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -409,6 +439,12 @@ paths: version: type: string example: WzIwNzMsMV0= + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 post: @@ -573,6 +609,12 @@ paths: examples: setCaseConfigResponse: $ref: '#/components/examples/set_case_configuration_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -728,6 +770,12 @@ paths: version: type: string example: WzIwNzMsMV0= + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -777,6 +825,12 @@ paths: examples: findConnectorResponse: $ref: '#/components/examples/find_connector_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -820,6 +874,12 @@ paths: examples: getReportersResponse: $ref: '#/components/examples/get_reporters_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -853,6 +913,12 @@ paths: examples: getStatusResponse: $ref: '#/components/examples/get_status_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -888,6 +954,12 @@ paths: examples: getTagsResponse: $ref: '#/components/examples/get_tags_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -920,6 +992,12 @@ paths: examples: getCaseResponse: $ref: '#/components/examples/get_case_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -948,6 +1026,12 @@ paths: examples: getCaseAlertsResponse: $ref: '#/components/examples/get_case_alerts_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -983,6 +1067,12 @@ paths: examples: createCaseCommentResponse: $ref: '#/components/examples/add_comment_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 delete: @@ -999,6 +1089,12 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 patch: @@ -1031,6 +1127,12 @@ paths: examples: updateCaseCommentResponse: $ref: '#/components/examples/update_comment_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 get: @@ -1051,6 +1153,12 @@ paths: application/json: schema: $ref: '#/components/schemas/case_response_properties' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -1071,6 +1179,12 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 get: @@ -1096,6 +1210,12 @@ paths: examples: getCaseCommentResponse: $ref: '#/components/examples/get_comment_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -1129,6 +1249,12 @@ paths: examples: pushCaseResponse: $ref: '#/components/examples/push_case_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -1157,6 +1283,12 @@ paths: examples: getCaseActivityResponse: $ref: '#/components/examples/get_case_activity_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -2004,6 +2136,18 @@ components: version: type: string example: WzUzMiwxXQ== + 4xx_response: + type: object + title: Unsuccessful cases API response + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 update_case_request: title: Update case request description: The update case API request body varies depending on the type of connector. diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/4xx_response.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/4xx_response.yaml new file mode 100644 index 0000000000000..75d0ac39903bf --- /dev/null +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/4xx_response.yaml @@ -0,0 +1,11 @@ +type: object +title: Unsuccessful cases API response +properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases.yaml index 98e36898e9685..ba4b852d96405 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases.yaml @@ -29,6 +29,12 @@ post: examples: createCaseResponse: $ref: '../components/examples/create_case_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 @@ -55,6 +61,12 @@ delete: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 @@ -90,6 +102,12 @@ patch: examples: updateCaseResponse: $ref: '../components/examples/update_case_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml index 65fbc2e1e2e40..e4eb42e73f0b2 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml @@ -163,6 +163,12 @@ get: examples: findCaseResponse: $ref: '../components/examples/find_case_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml index f12e48f4bb6b9..940f343c89386 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml @@ -30,7 +30,13 @@ get: description: The case title. example: - id: 06116b80-e1c3-11ec-be9b-9b1838238ee6 - title: security_case + title: security_case + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure.yaml index e95a6f5410149..cc17f044d437c 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure.yaml @@ -21,6 +21,12 @@ get: type: object properties: $ref: '../components/schemas/case_configure_response_properties.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 @@ -90,8 +96,13 @@ post: examples: setCaseConfigResponse: $ref: '../components/examples/set_case_configuration_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 - servers: - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@connectors@_find.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@connectors@_find.yaml index d6328b4426f7b..7cdd1bf63ae61 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@connectors@_find.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@connectors@_find.yaml @@ -23,6 +23,12 @@ get: examples: findConnectorResponse: $ref: '../components/examples/find_connector_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@{configurationid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@{configurationid}.yaml index c15c3ff5dc1d7..5f8dae09abf55 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@{configurationid}.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@{configurationid}.yaml @@ -50,6 +50,12 @@ patch: type: object properties: $ref: '../components/schemas/case_configure_response_properties.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@reporters.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@reporters.yaml index 171af68a417ba..51e57615f1216 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@reporters.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@reporters.yaml @@ -28,6 +28,12 @@ get: examples: getReportersResponse: $ref: '../components/examples/get_reporters_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@status.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@status.yaml index c3f4875e07ffd..a9db413e2eaef 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@status.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@status.yaml @@ -28,6 +28,12 @@ get: examples: getStatusResponse: $ref: '../components/examples/get_status_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@tags.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@tags.yaml index a4ce739c52b04..5e70cff6640e1 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@tags.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@tags.yaml @@ -30,7 +30,12 @@ get: examples: getTagsResponse: $ref: '../components/examples/get_tags_response.yaml' - + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}.yaml index d32d24b9fa01b..aca09f4a74420 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}.yaml @@ -27,6 +27,12 @@ get: examples: getCaseResponse: $ref: '../components/examples/get_case_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@alerts.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@alerts.yaml index abf2f26ce357b..aca587fe4886c 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@alerts.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@alerts.yaml @@ -23,6 +23,12 @@ get: examples: getCaseAlertsResponse: $ref: '../components/examples/get_case_alerts_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments.yaml index 25d119bd613c7..1b69926377ffb 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments.yaml @@ -31,6 +31,12 @@ post: examples: createCaseCommentResponse: $ref: '../components/examples/add_comment_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 @@ -50,6 +56,12 @@ delete: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 @@ -86,6 +98,12 @@ patch: examples: updateCaseCommentResponse: $ref: '../components/examples/update_comment_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 @@ -109,9 +127,13 @@ get: application/json: schema: $ref: '../components/schemas/case_response_properties.yaml' - + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 - servers: - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@{commentid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@{commentid}.yaml index f12e43158a99a..e43a2b2d81d65 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@{commentid}.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@{commentid}.yaml @@ -15,6 +15,12 @@ delete: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 @@ -43,8 +49,13 @@ get: examples: getCaseCommentResponse: $ref: '../components/examples/get_comment_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 - servers: - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml index 7c4ba981edd07..c378192592ce9 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml @@ -30,6 +30,12 @@ post: examples: pushCaseResponse: $ref: '../components/examples/push_case_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions.yaml index 43a6ec096dfaa..a21988cd5434f 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions.yaml @@ -23,6 +23,12 @@ get: examples: getCaseActivityResponse: $ref: '../components/examples/get_case_activity_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: From 1ca5cf9294c4643f7e7f3c88983562c30abd9f53 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Tue, 17 Jan 2023 18:07:44 +0100 Subject: [PATCH 06/44] [Index Management] Accept array of strings or string in copy_to field (#149002) --- .../constants/parameters_definition.tsx | 2 +- .../lib/mappings_validator.test.ts | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx index c00885de6b967..8c26701498f0d 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx @@ -448,7 +448,7 @@ export const PARAMETERS_DEFINITION: { [key in ParameterName]: ParameterDefinitio }, ], }, - schema: t.string, + schema: t.union([t.string, t.array(t.string)]), }, value: { fieldConfig: { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.test.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.test.ts index d41821bf3aeba..2006f72a7e35d 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.test.ts +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.test.ts @@ -183,6 +183,23 @@ describe('Properties validator', () => { expect(errors).toEqual([]); }); + it(`should allow copy_to to be an array of strings`, () => { + const properties = { + text1: { type: 'text', copy_to: ['field1', 'field2'] }, + field1: { type: 'text' }, + field2: { type: 'text' }, + }; + + const { value, errors } = validateProperties(properties as any); + + expect(value).toEqual({ + text1: { type: 'text', copy_to: ['field1', 'field2'] }, + field1: { type: 'text' }, + field2: { type: 'text' }, + }); + expect(errors).toEqual([]); + }); + it('should strip field whose type is not a string or is unknown', () => { const properties = { prop1: { type: 123 }, @@ -254,7 +271,7 @@ describe('Properties validator', () => { ignore_malformed: 0, null_value_numeric: 'abc', null_value_boolean: [], - copy_to: [], + copy_to: [1], max_input_length: true, locale: 1, orientation: [], From 4f6d0dff28221d449cc7f1631794bd7a619d8033 Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Tue, 17 Jan 2023 09:31:48 -0800 Subject: [PATCH 07/44] [DOCS] Create open API specification for create/update connector (#148691) --- .../connector-apis-passthru.asciidoc | 1098 ++++++- .../actions-and-connectors/create.asciidoc | 24 +- .../actions-and-connectors/update.asciidoc | 6 + .../plugins/actions/docs/openapi/bundled.json | 2706 ++++++++++++++++- .../plugins/actions/docs/openapi/bundled.yaml | 1953 +++++++++++- .../create_index_connector_request.yaml | 6 + .../create_index_connector_response.yaml | 12 + .../update_index_connector_request.yaml | 5 + .../config_properties_cases_webhook.yaml | 135 + .../schemas/config_properties_email.yaml | 5 + .../schemas/config_properties_index.yaml | 21 + .../schemas/config_properties_jira.yaml | 13 + .../schemas/config_properties_opsgenie.yaml | 12 + .../schemas/config_properties_pagerduty.yaml | 5 + .../schemas/config_properties_resilient.yaml | 13 + .../schemas/config_properties_servicenow.yaml | 41 + .../config_properties_servicenow_itom.yaml | 33 + .../schemas/config_properties_swimlane.yaml | 103 + .../schemas/config_properties_tines.yaml | 5 + .../schemas/config_properties_webhook.yaml | 5 + .../schemas/config_properties_xmatters.yaml | 5 + .../connector_response_properties.yaml | 22 + ...tor_response_properties_cases_webhook.yaml | 29 + .../connector_response_properties_email.yaml | 29 + .../connector_response_properties_index.yaml | 29 + .../connector_response_properties_jira.yaml | 29 + ...onnector_response_properties_opsgenie.yaml | 29 + ...nnector_response_properties_pagerduty.yaml | 29 + ...nnector_response_properties_resilient.yaml | 29 + ...nnector_response_properties_serverlog.yaml | 30 + ...nector_response_properties_servicenow.yaml | 29 + ...r_response_properties_servicenow_itom.yaml | 29 + ...or_response_properties_servicenow_sir.yaml | 29 + .../connector_response_properties_slack.yaml | 26 + ...onnector_response_properties_swimlane.yaml | 29 + .../connector_response_properties_teams.yaml | 26 + .../connector_response_properties_tines.yaml | 29 + ...connector_response_properties_webhook.yaml | 29 + ...onnector_response_properties_xmatters.yaml | 29 + .../components/schemas/connector_types.yaml | 1 + ...reate_connector_request_cases_webhook.yaml | 24 + .../create_connector_request_email.yaml | 27 + .../create_connector_request_index.yaml | 20 + .../create_connector_request_jira.yaml | 23 + .../create_connector_request_opsgenie.yaml | 23 + .../create_connector_request_pagerduty.yaml | 25 + .../create_connector_request_resilient.yaml | 23 + .../create_connector_request_serverlog.yaml | 17 + .../create_connector_request_servicenow.yaml | 25 + ...ate_connector_request_servicenow_itom.yaml | 25 + ...eate_connector_request_servicenow_sir.yaml | 25 + .../create_connector_request_slack.yaml | 20 + .../create_connector_request_swimlane.yaml | 23 + .../create_connector_request_teams.yaml | 20 + .../create_connector_request_tines.yaml | 24 + .../create_connector_request_webhook.yaml | 24 + .../create_connector_request_xmatters.yaml | 25 + .../schemas/mapping_properties_swimlane.yaml | 13 + .../secrets_properties_cases_webhook.yaml | 9 + .../schemas/secrets_properties_email.yaml | 5 + .../schemas/secrets_properties_jira.yaml | 13 + .../schemas/secrets_properties_opsgenie.yaml | 9 + .../schemas/secrets_properties_pagerduty.yaml | 5 + .../schemas/secrets_properties_resilient.yaml | 13 + .../secrets_properties_servicenow.yaml | 19 + .../schemas/secrets_properties_slack.yaml | 5 + .../schemas/secrets_properties_swimlane.yaml | 7 + .../schemas/secrets_properties_teams.yaml | 5 + .../schemas/secrets_properties_tines.yaml | 5 + .../schemas/secrets_properties_webhook.yaml | 5 + .../schemas/secrets_properties_xmatters.yaml | 5 + ...pdate_connector_request_cases_webhook.yaml | 14 + .../update_connector_request_email.yaml | 13 + .../update_connector_request_index.yaml | 11 + .../update_connector_request_jira.yaml | 14 + .../update_connector_request_opsgenie.yaml | 14 + .../update_connector_request_pagerduty.yaml | 14 + .../update_connector_request_resilient.yaml | 14 + .../update_connector_request_serverlog.yaml | 8 + .../update_connector_request_servicenow.yaml | 14 + ...ate_connector_request_servicenow_itom.yaml | 14 + .../update_connector_request_slack.yaml | 11 + .../update_connector_request_swimlane.yaml | 15 + .../update_connector_request_teams.yaml | 11 + .../update_connector_request_tines.yaml | 14 + .../update_connector_request_webhook.yaml | 14 + .../update_connector_request_xmatters.yaml | 14 + .../actions/docs/openapi/entrypoint.yaml | 4 +- .../s@{spaceid}@api@actions@connector.yaml | 69 + ...}@api@actions@connector@{connectorid}.yaml | 185 +- ...{spaceid}@api@actions@connector_types.yaml | 17 + .../s@{spaceid}@api@actions@connectors.yaml | 17 + 92 files changed, 7542 insertions(+), 187 deletions(-) create mode 100644 x-pack/plugins/actions/docs/openapi/components/examples/create_index_connector_request.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/examples/create_index_connector_response.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/examples/update_index_connector_request.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_cases_webhook.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_email.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_index.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_jira.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_opsgenie.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_pagerduty.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_resilient.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_servicenow.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_servicenow_itom.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_swimlane.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_tines.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_webhook.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_xmatters.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_cases_webhook.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_email.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_index.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_jira.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_opsgenie.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_pagerduty.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_resilient.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_serverlog.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow_itom.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow_sir.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_slack.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_swimlane.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_teams.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_tines.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_webhook.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_xmatters.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_cases_webhook.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_email.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_index.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_jira.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_opsgenie.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_pagerduty.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_resilient.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_serverlog.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_itom.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_sir.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_slack.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_swimlane.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_teams.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_tines.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_webhook.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_xmatters.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/mapping_properties_swimlane.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_cases_webhook.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_email.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_jira.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_opsgenie.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_pagerduty.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_resilient.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_servicenow.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_slack.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_swimlane.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_teams.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_tines.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_webhook.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_xmatters.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_cases_webhook.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_email.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_index.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_jira.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_opsgenie.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_pagerduty.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_resilient.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_serverlog.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_servicenow.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_servicenow_itom.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_slack.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_swimlane.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_teams.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_tines.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_webhook.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_xmatters.yaml create mode 100644 x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector.yaml diff --git a/docs/api-generated/connectors/connector-apis-passthru.asciidoc b/docs/api-generated/connectors/connector-apis-passthru.asciidoc index 03a22d9addfde..ac2c18b4f2c29 100644 --- a/docs/api-generated/connectors/connector-apis-passthru.asciidoc +++ b/docs/api-generated/connectors/connector-apis-passthru.asciidoc @@ -18,13 +18,81 @@ Any modifications made to this file will be overwritten.

Connectors

Connectors

+
+
+ Up +
post /s/{spaceId}/api/actions/connector
+
Creates a connector. (createConnector)
+
You must have all privileges for the Actions and Connectors feature in the Management section of the Kibana feature privileges.
+ +

Path parameters

+
+
spaceId (required)
+ +
Path Parameter — An identifier for the space. If /s/ and the identifier are omitted from the path, the default space is used. default: null
+
+ +

Consumes

+ This API call consumes the following media types via the Content-Type request header: +
    +
  • application/json
  • +
+ +

Request body

+
+
Create_connector_request_body_properties Create_connector_request_body_properties (required)
+ +
Body Parameter
+ +
+ +

Request headers

+
+
kbn-xsrf (required)
+ +
Header Parameter — default: null
+ +
+ + + +

Return type

+ + + + +

Example data

+
Content-Type: application/json
+
null
+ +

Produces

+ This API call produces the following media types according to the Accept request header; + the media type will be conveyed by the Content-Type response header. +
    +
  • application/json
  • +
+ +

Responses

+

200

+ Indicates a successful call. + connector_response_properties +

401

+ Authorization information is missing or invalid. + createConnector_401_response +
+
Up @@ -57,11 +125,23 @@ Any modifications made to this file will be overwritten. +

Produces

+ This API call produces the following media types according to the Accept request header; + the media type will be conveyed by the Content-Type response header. +
    +
  • application/json
  • +

Responses

204

Indicates a successful call. +

401

+ Authorization information is missing or invalid. + createConnector_401_response +

404

+ Object is not found. + getConnector_404_response

@@ -87,7 +167,7 @@ Any modifications made to this file will be overwritten.

Return type

@@ -95,17 +175,7 @@ Any modifications made to this file will be overwritten.

Example data

Content-Type: application/json
-
{
-  "is_missing_secrets" : false,
-  "is_deprecated" : false,
-  "is_preconfigured" : false,
-  "name" : "my-connector",
-  "id" : "b0766e10-d190-11ec-b04c-776c77d14fca",
-  "config" : {
-    "key" : ""
-  },
-  "connector_type_id" : ".server-log"
-}
+
null

Produces

This API call produces the following media types according to the Accept request header; @@ -117,7 +187,13 @@ Any modifications made to this file will be overwritten.

Responses

200

Indicates a successful call. - getConnector_200_response + connector_response_properties +

401

+ Authorization information is missing or invalid. + createConnector_401_response +

404

+ Object is not found. + getConnector_404_response

@@ -147,7 +223,7 @@ Any modifications made to this file will be overwritten.

Return type

@@ -176,6 +252,9 @@ Any modifications made to this file will be overwritten.

200

Indicates a successful call. +

401

+ Authorization information is missing or invalid. + createConnector_401_response

@@ -199,7 +278,7 @@ Any modifications made to this file will be overwritten.

Return type

@@ -231,6 +310,83 @@ Any modifications made to this file will be overwritten.

200

Indicates a successful call. +

401

+ Authorization information is missing or invalid. + createConnector_401_response +
+
+
+
+ Up +
put /s/{spaceId}/api/actions/connector/{connectorId}
+
Updates the attributes for a connector. (updateConnector)
+
You must have all privileges for the Actions and Connectors feature in the Management section of the Kibana feature privileges.
+ +

Path parameters

+
+
connectorId (required)
+ +
Path Parameter — An identifier for the connector. default: null
spaceId (required)
+ +
Path Parameter — An identifier for the space. If /s/ and the identifier are omitted from the path, the default space is used. default: null
+
+ +

Consumes

+ This API call consumes the following media types via the Content-Type request header: +
    +
  • application/json
  • +
+ +

Request body

+
+
Update_connector_request_body_properties Update_connector_request_body_properties (required)
+ +
Body Parameter
+ +
+ +

Request headers

+
+
kbn-xsrf (required)
+ +
Header Parameter — default: null
+ +
+ + + +

Return type

+ + + + +

Example data

+
Content-Type: application/json
+
null
+ +

Produces

+ This API call produces the following media types according to the Accept request header; + the media type will be conveyed by the Content-Type response header. +
    +
  • application/json
  • +
+ +

Responses

+

200

+ Indicates a successful call. + connector_response_properties +

400

+ Indicates a bad request. + updateConnector_400_response +

401

+ Authorization information is missing or invalid. + createConnector_401_response +

404

+ Object is not found. + getConnector_404_response

@@ -239,27 +395,160 @@ Any modifications made to this file will be overwritten.

Table of Contents

    -
  1. connector_types -
  2. +
  3. Alert_identifier_mapping - Alert identifier mapping
  4. +
  5. Case_comment_mapping - Case comment mapping
  6. +
  7. Case_description_mapping - Case description mapping
  8. +
  9. Case_identifier_mapping - Case identifier mapping
  10. +
  11. Case_name_mapping - Case name mapping
  12. +
  13. Connector_mappings_properties_for_a_Swimlane_connector - Connector mappings properties for a Swimlane connector
  14. +
  15. Create_connector_request_body_properties - Create connector request body properties
  16. +
  17. Get_connector_types_response_body_properties_inner -
  18. +
  19. Get_connectors_response_body_properties - Get connectors response body properties
  20. +
  21. Rule_name_mapping - Rule name mapping
  22. +
  23. Severity_mapping - Severity mapping
  24. +
  25. Update_connector_request_body_properties - Update connector request body properties
  26. +
  27. config_properties_cases_webhook - Connector request properties for Webhook - Case Management connector
  28. +
  29. config_properties_index - Connector request properties for an index connector
  30. +
  31. config_properties_jira - Connector request properties for a Jira connector
  32. +
  33. config_properties_opsgenie - Connector request properties for an Opsgenie connector
  34. +
  35. config_properties_resilient - Connector request properties for a IBM Resilient connector
  36. +
  37. config_properties_servicenow - Connector request properties for a ServiceNow ITSM connector
  38. +
  39. config_properties_servicenow_itom - Connector request properties for a ServiceNow ITSM connector
  40. +
  41. config_properties_swimlane - Connector request properties for a Swimlane connector
  42. +
  43. connector_response_properties - Connector response properties
  44. +
  45. connector_response_properties_cases_webhook - Connector request properties for a Webhook - Case Management connector
  46. +
  47. connector_response_properties_email - Connector response properties for an email connector
  48. +
  49. connector_response_properties_index - Connector response properties for an index connector
  50. +
  51. connector_response_properties_jira - Connector response properties for a Jira connector
  52. +
  53. connector_response_properties_opsgenie - Connector response properties for an Opsgenie connector
  54. +
  55. connector_response_properties_pagerduty - Connector response properties for a PagerDuty connector
  56. +
  57. connector_response_properties_resilient - Connector response properties for a IBM Resilient connector
  58. +
  59. connector_response_properties_serverlog - Connector response properties for a server log connector
  60. +
  61. connector_response_properties_servicenow - Connector response properties for a ServiceNow ITSM connector
  62. +
  63. connector_response_properties_servicenow_itom - Connector response properties for a ServiceNow ITOM connector
  64. +
  65. connector_response_properties_servicenow_sir - Connector response properties for a ServiceNow SecOps connector
  66. +
  67. connector_response_properties_slack - Connector response properties for a Slack connector
  68. +
  69. connector_response_properties_swimlane - Connector response properties for a Swimlane connector
  70. +
  71. connector_response_properties_teams - Connector response properties for a Microsoft Teams connector
  72. +
  73. connector_response_properties_tines - Connector response properties for a Tines connector
  74. +
  75. connector_response_properties_webhook - Connector response properties for a Webhook connector
  76. +
  77. connector_response_properties_xmatters - Connector response properties for an xMatters connector
  78. +
  79. connector_types - Connector types
  80. +
  81. createConnector_401_response -
  82. +
  83. create_connector_request_cases_webhook - Create Webhook - Case Managment connector request
  84. +
  85. create_connector_request_email - Create email connector request
  86. +
  87. create_connector_request_index - Create index connector request
  88. +
  89. create_connector_request_jira - Create Jira connector request
  90. +
  91. create_connector_request_opsgenie - Create Opsgenie connector request
  92. +
  93. create_connector_request_pagerduty - Create PagerDuty connector request
  94. +
  95. create_connector_request_resilient - Create IBM Resilient connector request
  96. +
  97. create_connector_request_serverlog - Create server log connector request
  98. +
  99. create_connector_request_servicenow - Create ServiceNow ITSM connector request
  100. +
  101. create_connector_request_servicenow_itom - Create ServiceNow ITOM connector request
  102. +
  103. create_connector_request_servicenow_sir - Create ServiceNow SecOps connector request
  104. +
  105. create_connector_request_slack - Create Slack connector request
  106. +
  107. create_connector_request_swimlane - Create Swimlane connector request
  108. +
  109. create_connector_request_teams - Create Microsoft Teams connector request
  110. +
  111. create_connector_request_tines - Create Tines connector request
  112. +
  113. create_connector_request_webhook - Create Webhook connector request
  114. +
  115. create_connector_request_xmatters - Create xMatters connector request
  116. features -
  117. -
  118. getConnectorTypes_200_response_inner -
  119. -
  120. getConnector_200_response -
  121. -
  122. getConnectors_200_response_inner -
  123. +
  124. getConnector_404_response -
  125. +
  126. secrets_properties_cases_webhook - Connector secrets properties for Webhook - Case Management connector
  127. +
  128. secrets_properties_jira - Connector secrets properties for a Jira connector
  129. +
  130. secrets_properties_opsgenie - Connector secrets properties for an Opsgenie connector
  131. +
  132. secrets_properties_resilient - Connector secrets properties for IBM Resilient connector
  133. +
  134. secrets_properties_servicenow - Connector secrets properties for ServiceNow ITOM, ServiceNow ITSM, and ServiceNow SecOps connectors
  135. +
  136. secrets_properties_swimlane - Connector secrets properties for a Swimlane connector
  137. +
  138. updateConnector_400_response -
  139. +
  140. update_connector_request_cases_webhook - Update Webhook - Case Managment connector request
  141. +
  142. update_connector_request_index - Update index connector request
  143. +
  144. update_connector_request_jira - Update Jira connector request
  145. +
  146. update_connector_request_opsgenie - Update Opsgenie connector request
  147. +
  148. update_connector_request_resilient - Update IBM Resilient connector request
  149. +
  150. update_connector_request_serverlog - Update server log connector request
  151. +
  152. update_connector_request_servicenow - Update ServiceNow ITSM connector or ServiceNow SecOps request
  153. +
  154. update_connector_request_servicenow_itom - Create ServiceNow ITOM connector request
  155. +
  156. update_connector_request_swimlane - Update Swimlane connector request
-

connector_types - Up

-
The type of connector. For example, .email, .index, .jira, .opsgenie, or .server-log.
+

Alert_identifier_mapping - Alert identifier mapping Up

+
Mapping for the alert ID.
-
+
fieldType
String The type of field in Swimlane.
+
id
String The identifier for the field in Swimlane.
+
key
String The key for the field in Swimlane.
+
name
String The name of the field in Swimlane.
+
-

features - Up

-
The feature that uses the connector. Valid values are alerting, cases, uptime, and siem.
+

Case_comment_mapping - Case comment mapping Up

+
Mapping for the case comments.
-
+
fieldType
String The type of field in Swimlane.
+
id
String The identifier for the field in Swimlane.
+
key
String The key for the field in Swimlane.
+
name
String The name of the field in Swimlane.
+
-

getConnectorTypes_200_response_inner - Up

+

Case_description_mapping - Case description mapping Up

+
Mapping for the case description.
+
+
fieldType
String The type of field in Swimlane.
+
id
String The identifier for the field in Swimlane.
+
key
String The key for the field in Swimlane.
+
name
String The name of the field in Swimlane.
+
+
+
+

Case_identifier_mapping - Case identifier mapping Up

+
Mapping for the case ID.
+
+
fieldType
String The type of field in Swimlane.
+
id
String The identifier for the field in Swimlane.
+
key
String The key for the field in Swimlane.
+
name
String The name of the field in Swimlane.
+
+
+
+

Case_name_mapping - Case name mapping Up

+
Mapping for the case name.
+
+
fieldType
String The type of field in Swimlane.
+
id
String The identifier for the field in Swimlane.
+
key
String The key for the field in Swimlane.
+
name
String The name of the field in Swimlane.
+
+
+
+

Connector_mappings_properties_for_a_Swimlane_connector - Connector mappings properties for a Swimlane connector Up

+
The field mapping.
+
+
alertIdConfig (optional)
+
caseIdConfig (optional)
+
caseNameConfig (optional)
+
commentsConfig (optional)
+
descriptionConfig (optional)
+
ruleNameConfig (optional)
+
severityConfig (optional)
+
+
+
+

Create_connector_request_body_properties - Create connector request body properties Up

+
The properties vary depending on the connector type.
+
+
config
map[String, oas_any_type_not_mapped] Defines properties for connectors when type is .xmatters.
+
connector_type_id
String The type of connector.
+
Enum:
+
.xmatters
+
name
String The display name for the connector.
+
secrets
map[String, oas_any_type_not_mapped] Defines secrets for connectors when type is .xmatters.
+
+
+
+

Get_connector_types_response_body_properties_inner - Up

enabled (optional)
Boolean Indicates whether the connector type is enabled in Kibana.
@@ -272,11 +561,165 @@ Any modifications made to this file will be overwritten.
-

getConnector_200_response - Up

+

Get_connectors_response_body_properties - Get connectors response body properties Up

+
The properties vary for each connector type.
+
+
connector_type_id
+
config (optional)
map[String, oas_any_type_not_mapped] The configuration for the connector. Configuration properties vary depending on the connector type.
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
referenced_by_count
Integer Indicates the number of saved objects that reference the connector. If is_preconfigured is true, this value is not calculated.
+
+
+
+

Rule_name_mapping - Rule name mapping Up

+
Mapping for the name of the alert's rule.
+
+
fieldType
String The type of field in Swimlane.
+
id
String The identifier for the field in Swimlane.
+
key
String The key for the field in Swimlane.
+
name
String The name of the field in Swimlane.
+
+
+
+

Severity_mapping - Severity mapping Up

+
Mapping for the severity.
+
+
fieldType
String The type of field in Swimlane.
+
id
String The identifier for the field in Swimlane.
+
key
String The key for the field in Swimlane.
+
name
String The name of the field in Swimlane.
+
+
+
+

Update_connector_request_body_properties - Update connector request body properties Up

+
The properties vary depending on the connector type.
+
+
config
+
name
String The display name for the connector.
+
secrets
+
+
+
+

config_properties_cases_webhook - Connector request properties for Webhook - Case Management connector Up

+
Defines properties for connectors when type is .cases-webhook.
+
+
createCommentJson (optional)
String A JSON payload sent to the create comment URL to create a case comment. You can use variables to add Kibana Cases data to the payload. The required variable is case.comment. Due to Mustache template variables (the text enclosed in triple braces, for example, {{{case.title}}}), the JSON is not validated when you create the connector. The JSON is validated once the Mustache variables have been placed when the REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass.
+
createCommentMethod (optional)
String The REST API HTTP request method to create a case comment in the third-party system. Valid values are patch, post, and put.
+
Enum:
+
patch
post
put
+
createCommentUrl (optional)
String The REST API URL to create a case comment by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the xpack.actions.allowedHosts setting, add the hostname to the allowed hosts.
+
createIncidentJson
String A JSON payload sent to the create case URL to create a case. You can use variables to add case data to the payload. Required variables are case.title and case.description. Due to Mustache template variables (which is the text enclosed in triple braces, for example, {{{case.title}}}), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review.
+
createIncidentMethod (optional)
String The REST API HTTP request method to create a case in the third-party system. Valid values are patch, post, and put.
+
Enum:
+
patch
post
put
+
createIncidentResponseKey
String The JSON key in the create case response that contains the external case ID.
+
createIncidentUrl
String The REST API URL to create a case in the third-party system. If you are using the xpack.actions.allowedHosts setting, add the hostname to the allowed hosts.
+
getIncidentResponseExternalTitleKey
String The JSON key in get case response that contains the external case title.
+
getIncidentUrl
String The REST API URL to get the case by ID from the third-party system. If you are using the xpack.actions.allowedHosts setting, add the hostname to the allowed hosts. You can use a variable to add the external system ID to the URL. Due to Mustache template variables (the text enclosed in triple braces, for example, {{{case.title}}}), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass.
+
hasAuth (optional)
Boolean If true, a username and password for login type authentication must be provided.
+
headers (optional)
String A set of key-value pairs sent as headers with the request URLs for the create case, update case, get case, and create comment methods.
+
updateIncidentJson
String The JSON payload sent to the update case URL to update the case. You can use variables to add Kibana Cases data to the payload. Required variables are case.title and case.description. Due to Mustache template variables (which is the text enclosed in triple braces, for example, {{{case.title}}}), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review.
+
updateIncidentMethod (optional)
String The REST API HTTP request method to update the case in the third-party system. Valid values are patch, post, and put.
+
Enum:
+
patch
post
put
+
updateIncidentUrl
String The REST API URL to update the case by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the xpack.actions.allowedHosts setting, add the hostname to the allowed hosts.
+
viewIncidentUrl
String The URL to view the case in the external system. You can use variables to add the external system ID or external system title to the URL.
+
+
+
+

config_properties_index - Connector request properties for an index connector Up

+
Defines properties for connectors when type is .index.
+
+
executionTimeField (optional)
String Specifies a field that will contain the time the alert condition was detected.
+
index
String The Elasticsearch index to be written to.
+
refresh (optional)
Boolean The refresh policy for the write request, which affects when changes are made visible to search. Refer to the refresh setting for Elasticsearch document APIs.
+
+
+
+

config_properties_jira - Connector request properties for a Jira connector Up

+
Defines properties for connectors when type is .jira.
+
+
apiUrl
String The Jira instance URL.
+
projectKey
String The Jira project key.
+
+
+
+

config_properties_opsgenie - Connector request properties for an Opsgenie connector Up

+
Defines properties for connectors when type is .opsgenie.
+
+
apiUrl
String The Opsgenie URL. For example, https://api.opsgenie.com or https://api.eu.opsgenie.com. If you are using the xpack.actions.allowedHosts setting, add the hostname to the allowed hosts.
+
+
+
+

config_properties_resilient - Connector request properties for a IBM Resilient connector Up

+
Defines properties for connectors when type is .resilient.
+
+
apiUrl
String The IBM Resilient instance URL.
+
orgId
String The IBM Resilient organization ID.
+
+
+
+

config_properties_servicenow - Connector request properties for a ServiceNow ITSM connector Up

+
Defines properties for connectors when type is .servicenow.
+
+
apiUrl
String The ServiceNow instance URL.
+
clientId (optional)
String The client ID assigned to your OAuth application. This property is required when isOAuth is true.
+
isOAuth (optional)
String The type of authentication to use. The default value is false, which means basic authentication is used instead of open authorization (OAuth).
+
jwtKeyId (optional)
String The key identifier assigned to the JWT verifier map of your OAuth application. This property is required when isOAuth is true.
+
userIdentifierValue (optional)
String The identifier to use for OAuth authentication. This identifier should be the user field you selected when you created an OAuth JWT API endpoint for external clients in your ServiceNow instance. For example, if the selected user field is Email, the user identifier should be the user's email address. This property is required when isOAuth is true.
+
usesTableApi (optional)
Boolean Determines whether the connector uses the Table API or the Import Set API. This property is supported only for ServiceNow ITSM and ServiceNow SecOps connectors. NOTE: If this property is set to false, the Elastic application should be installed in ServiceNow.
+
+
+
+

config_properties_servicenow_itom - Connector request properties for a ServiceNow ITSM connector Up

+
Defines properties for connectors when type is .servicenow.
+
+
apiUrl
String The ServiceNow instance URL.
+
clientId (optional)
String The client ID assigned to your OAuth application. This property is required when isOAuth is true.
+
isOAuth (optional)
String The type of authentication to use. The default value is false, which means basic authentication is used instead of open authorization (OAuth).
+
jwtKeyId (optional)
String The key identifier assigned to the JWT verifier map of your OAuth application. This property is required when isOAuth is true.
+
userIdentifierValue (optional)
String The identifier to use for OAuth authentication. This identifier should be the user field you selected when you created an OAuth JWT API endpoint for external clients in your ServiceNow instance. For example, if the selected user field is Email, the user identifier should be the user's email address. This property is required when isOAuth is true.
+
+
+
+

config_properties_swimlane - Connector request properties for a Swimlane connector Up

+
Defines properties for connectors when type is .swimlane.
+
+
apiUrl
String The Swimlane instance URL.
+
appId
String The Swimlane application ID.
+
connectorType
String The type of connector. Valid values are all, alerts, and cases.
+
Enum:
+
all
alerts
cases
+
mappings (optional)
+
+
+
+

connector_response_properties - Connector response properties Up

+
The properties vary depending on the connector type.
+
+
config
map[String, oas_any_type_not_mapped] Defines properties for connectors when type is .xmatters.
+
connector_type_id
String The type of connector.
+
Enum:
+
.xmatters
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_response_properties_cases_webhook - Connector request properties for a Webhook - Case Management connector Up

-
config (optional)
map[String, oas_any_type_not_mapped] The configuration for the connector. Configuration properties vary depending on the connector type.
-
connector_type_id
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.cases-webhook
id
String The identifier for the connector.
is_deprecated
Boolean Indicates whether the connector type is deprecated.
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
@@ -285,17 +728,606 @@ Any modifications made to this file will be overwritten.
-

getConnectors_200_response_inner - Up

+

connector_response_properties_email - Connector response properties for an email connector Up

-
connector_type_id
-
config (optional)
map[String, oas_any_type_not_mapped] The configuration for the connector. Configuration properties vary depending on the connector type.
+
config
map[String, oas_any_type_not_mapped] Defines properties for connectors when type is .email.
+
connector_type_id
String The type of connector.
+
Enum:
+
.email
id
String The identifier for the connector.
is_deprecated
Boolean Indicates whether the connector type is deprecated.
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
name
String The display name for the connector.
-
referenced_by_count
Integer Indicates the number of saved objects that reference the connector. If is_preconfigured is true, this value is not calculated.
+
+
+
+

connector_response_properties_index - Connector response properties for an index connector Up

+
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.index
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_response_properties_jira - Connector response properties for a Jira connector Up

+
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.jira
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_response_properties_opsgenie - Connector response properties for an Opsgenie connector Up

+
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.opsgenie
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_response_properties_pagerduty - Connector response properties for a PagerDuty connector Up

+
+
+
config
map[String, oas_any_type_not_mapped] Defines properties for connectors when type is .pagerduty.
+
connector_type_id
String The type of connector.
+
Enum:
+
.pagerduty
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_response_properties_resilient - Connector response properties for a IBM Resilient connector Up

+
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.resilient
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_response_properties_serverlog - Connector response properties for a server log connector Up

+
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.server-log
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_response_properties_servicenow - Connector response properties for a ServiceNow ITSM connector Up

+
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.servicenow
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_response_properties_servicenow_itom - Connector response properties for a ServiceNow ITOM connector Up

+
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.servicenow-itom
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_response_properties_servicenow_sir - Connector response properties for a ServiceNow SecOps connector Up

+
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.servicenow-sir
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_response_properties_slack - Connector response properties for a Slack connector Up

+
+
+
connector_type_id
String The type of connector.
+
Enum:
+
.slack
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_response_properties_swimlane - Connector response properties for a Swimlane connector Up

+
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.swimlane
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_response_properties_teams - Connector response properties for a Microsoft Teams connector Up

+
+
+
connector_type_id
String The type of connector.
+
Enum:
+
.teams
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_response_properties_tines - Connector response properties for a Tines connector Up

+
+
+
config
map[String, oas_any_type_not_mapped] Defines properties for connectors when type is .tines.
+
connector_type_id
String The type of connector.
+
Enum:
+
.tines
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_response_properties_webhook - Connector response properties for a Webhook connector Up

+
+
+
config
map[String, oas_any_type_not_mapped] Defines properties for connectors when type is .webhook.
+
connector_type_id
String The type of connector.
+
Enum:
+
.webhook
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_response_properties_xmatters - Connector response properties for an xMatters connector Up

+
+
+
config
map[String, oas_any_type_not_mapped] Defines properties for connectors when type is .xmatters.
+
connector_type_id
String The type of connector.
+
Enum:
+
.xmatters
+
id
String The identifier for the connector.
+
is_deprecated
Boolean Indicates whether the connector type is deprecated.
+
is_missing_secrets (optional)
Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
+
is_preconfigured
Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
+
name
String The display name for the connector.
+
+
+
+

connector_types - Connector types Up

+
The type of connector. For example, .email, .index, .jira, .opsgenie, or .server-log.
+
+
+
+
+

createConnector_401_response - Up

+
+
+
error (optional)
+
message (optional)
+
statusCode (optional)
+
+
+
+

create_connector_request_cases_webhook - Create Webhook - Case Managment connector request Up

+
The Webhook - Case Management connector uses axios to send POST, PUT, and GET requests to a case management RESTful API web service.
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.cases-webhook
+
name
String The display name for the connector.
+
secrets (optional)
+
+
+
+

create_connector_request_email - Create email connector request Up

+
The email connector uses the SMTP protocol to send mail messages, using an integration of Nodemailer. An exception is Microsoft Exchange, which uses HTTP protocol for sending emails, Send mail. Email message text is sent as both plain text and html text.
+
+
config
map[String, oas_any_type_not_mapped] Defines properties for connectors when type is .email.
+
connector_type_id
String The type of connector.
+
Enum:
+
.email
+
name
String The display name for the connector.
+
secrets
map[String, oas_any_type_not_mapped] Defines secrets for connectors when type is .email.
+
+
+
+

create_connector_request_index - Create index connector request Up

+
The index connector indexes a document into Elasticsearch.
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.index
+
name
String The display name for the connector.
+
+
+
+

create_connector_request_jira - Create Jira connector request Up

+
The Jira connector uses the REST API v2 to create Jira issues.
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.jira
+
name
String The display name for the connector.
+
secrets
+
+
+
+

create_connector_request_opsgenie - Create Opsgenie connector request Up

+
The Opsgenie connector uses the Opsgenie alert API.
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.opsgenie
+
name
String The display name for the connector.
+
secrets
+
+
+
+

create_connector_request_pagerduty - Create PagerDuty connector request Up

+
The PagerDuty connector uses the v2 Events API to trigger, acknowledge, and resolve PagerDuty alerts.
+
+
config
map[String, oas_any_type_not_mapped] Defines properties for connectors when type is .pagerduty.
+
connector_type_id
String The type of connector.
+
Enum:
+
.pagerduty
+
name
String The display name for the connector.
+
secrets
map[String, oas_any_type_not_mapped] Defines secrets for connectors when type is .pagerduty.
+
+
+
+

create_connector_request_resilient - Create IBM Resilient connector request Up

+
The IBM Resilient connector uses the RESILIENT REST v2 to create IBM Resilient incidents.
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.resilient
+
name
String The display name for the connector.
+
secrets
+
+
+
+

create_connector_request_serverlog - Create server log connector request Up

+
This connector writes an entry to the Kibana server log.
+
+
connector_type_id
String The type of connector.
+
Enum:
+
.server-log
+
name
String The display name for the connector.
+
+
+
+

create_connector_request_servicenow - Create ServiceNow ITSM connector request Up

+
The ServiceNow ITSM connector uses the import set API to create ServiceNow incidents. You can use the connector for rule actions and cases.
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.servicenow
+
name
String The display name for the connector.
+
secrets
+
+
+
+

create_connector_request_servicenow_itom - Create ServiceNow ITOM connector request Up

+
The ServiceNow ITOM connector uses the event API to create ServiceNow events. You can use the connector for rule actions.
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.servicenow-itom
+
name
String The display name for the connector.
+
secrets
+
+
+
+

create_connector_request_servicenow_sir - Create ServiceNow SecOps connector request Up

+
The ServiceNow SecOps connector uses the import set API to create ServiceNow security incidents. You can use the connector for rule actions and cases.
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.servicenow-sir
+
name
String The display name for the connector.
+
secrets
+
+
+
+

create_connector_request_slack - Create Slack connector request Up

+
The Slack connector uses Slack Incoming Webhooks.
+
+
connector_type_id
String The type of connector.
+
Enum:
+
.slack
+
name
String The display name for the connector.
+
secrets
map[String, oas_any_type_not_mapped] Defines secrets for connectors when type is .slack.
+
+
+
+

create_connector_request_swimlane - Create Swimlane connector request Up

+
The Swimlane connector uses the Swimlane REST API to create Swimlane records.
+
+
config
+
connector_type_id
String The type of connector.
+
Enum:
+
.swimlane
+
name
String The display name for the connector.
+
secrets
+
+
+
+

create_connector_request_teams - Create Microsoft Teams connector request Up

+
The Microsoft Teams connector uses Incoming Webhooks.
+
+
connector_type_id
String The type of connector.
+
Enum:
+
.teams
+
name
String The display name for the connector.
+
secrets
map[String, oas_any_type_not_mapped] Defines secrets for connectors when type is .teams.
+
+
+
+

create_connector_request_tines - Create Tines connector request Up

+
The Tines connector uses Tines Webhook actions to send events via POST request.
+
+
config
map[String, oas_any_type_not_mapped] Defines properties for connectors when type is .tines.
+
connector_type_id
String The type of connector.
+
Enum:
+
.tines
+
name
String The display name for the connector.
+
secrets
map[String, oas_any_type_not_mapped] Defines secrets for connectors when type is .tines.
+
+
+
+

create_connector_request_webhook - Create Webhook connector request Up

+
The Webhook connector uses axios to send a POST or PUT request to a web service.
+
+
config
map[String, oas_any_type_not_mapped] Defines properties for connectors when type is .webhook.
+
connector_type_id
String The type of connector.
+
Enum:
+
.webhook
+
name
String The display name for the connector.
+
secrets
map[String, oas_any_type_not_mapped] Defines secrets for connectors when type is .webhook.
+
+
+
+

create_connector_request_xmatters - Create xMatters connector request Up

+
The xMatters connector uses the xMatters Workflow for Elastic to send actionable alerts to on-call xMatters resources.
+
+
config
map[String, oas_any_type_not_mapped] Defines properties for connectors when type is .xmatters.
+
connector_type_id
String The type of connector.
+
Enum:
+
.xmatters
+
name
String The display name for the connector.
+
secrets
map[String, oas_any_type_not_mapped] Defines secrets for connectors when type is .xmatters.
+
+
+
+

features - Up

+
The feature that uses the connector. Valid values are alerting, cases, uptime, and siem.
+
+
+
+
+

getConnector_404_response - Up

+
+
+
error (optional)
+
message (optional)
+
statusCode (optional)
+
+
+
+

secrets_properties_cases_webhook - Connector secrets properties for Webhook - Case Management connector Up

+
+
+
password (optional)
String The password for HTTP basic authentication. If hasAuth is set to true, this property is required.
+
user (optional)
String The username for HTTP basic authentication. If hasAuth is set to true, this property is required.
+
+
+
+

secrets_properties_jira - Connector secrets properties for a Jira connector Up

+
Defines secrets for connectors when type is .jira.
+
+
apiToken
String The Jira API authentication token for HTTP basic authentication.
+
email
String The account email for HTTP Basic authentication.
+
+
+
+

secrets_properties_opsgenie - Connector secrets properties for an Opsgenie connector Up

+
Defines secrets for connectors when type is .opsgenie.
+
+
apiKey
String The Opsgenie API authentication key for HTTP Basic authentication.
+
+
+
+

secrets_properties_resilient - Connector secrets properties for IBM Resilient connector Up

+
Defines secrets for connectors when type is .resilient.
+
+
apiKeyId
String The authentication key ID for HTTP Basic authentication.
+
apiKeySecret
String The authentication key secret for HTTP Basic authentication.
+
+
+
+

secrets_properties_servicenow - Connector secrets properties for ServiceNow ITOM, ServiceNow ITSM, and ServiceNow SecOps connectors Up

+
Defines secrets for connectors when type is .servicenow, .servicenow-sir, or .servicenow-itom.
+
+
clientSecret (optional)
String The client secret assigned to your OAuth application. This property is required when isOAuth is true.
+
password (optional)
String The password for HTTP basic authentication. This property is required when isOAuth is false.
+
privateKey (optional)
String The RSA private key that you created for use in ServiceNow. This property is required when isOAuth is true.
+
privateKeyPassword (optional)
String The password for the RSA private key. This property is required when isOAuth is true and you set a password on your private key.
+
username (optional)
String The username for HTTP basic authentication. This property is required when isOAuth is false.
+
+
+
+

secrets_properties_swimlane - Connector secrets properties for a Swimlane connector Up

+
Defines secrets for connectors when type is .swimlane.
+
+
apiToken (optional)
String Swimlane API authentication token.
+
+
+
+

updateConnector_400_response - Up

+
+
+
error (optional)
+
message (optional)
+
statusCode (optional)
+
+
+ +
+

update_connector_request_index - Update index connector request Up

+
+
+
config
+
name
String The display name for the connector.
+
+
+
+

update_connector_request_jira - Update Jira connector request Up

+
+
+
config
+
name
String The display name for the connector.
+
secrets
+
+
+ + +
+

update_connector_request_serverlog - Update server log connector request Up

+
+
+
name
String The display name for the connector.
+
+
+ + +
diff --git a/docs/api/actions-and-connectors/create.asciidoc b/docs/api/actions-and-connectors/create.asciidoc index cdaab61e5581e..259c5dfee00af 100644 --- a/docs/api/actions-and-connectors/create.asciidoc +++ b/docs/api/actions-and-connectors/create.asciidoc @@ -6,6 +6,12 @@ Creates a connector. +[NOTE] +==== +For the most up-to-date API details, refer to the +{kib-repo}/tree/{branch}/x-pack/plugins/actions/docs/openapi[open API specification]. For a preview, check out <>. +==== + [[create-connector-api-request]] === {api-request-title} @@ -121,9 +127,9 @@ the selected user field is `Email`, the user identifier should be the user's email address. This property is required when `isOAuth` is `true`. `usesTableApi`:: -(Optional, string) Determines whether the connector uses the Table API or the +(Optional, boolean) Determines whether the connector uses the Table API or the Import Set API. This property is supported only for {sn-itsm} and {sn-sir} -connectors. +connectors. The default value is `true`. + NOTE: If this property is set to false, the Elastic application should be installed in {sn}. @@ -152,7 +158,7 @@ installed in {sn}. (Optional, object) Mapping for the alert ID. `fieldType`:::: -(Required, object) The type of the field in {swimlane}. +(Required, string) The type of the field in {swimlane}. `id`:::: (Required, string) The id of the field in {swimlane}. @@ -167,7 +173,7 @@ installed in {sn}. (Optional, object) Mapping for the case ID. `fieldType`:::: -(Required, object) The type of the field in {swimlane}. +(Required, string) The type of the field in {swimlane}. `id`:::: (Required, string) The id of the field in {swimlane}. @@ -182,7 +188,7 @@ installed in {sn}. (Optional, object) Mapping for the case name. `fieldType`:::: -(Required, object) The type of the field in {swimlane}. +(Required, string) The type of the field in {swimlane}. `id`:::: (Required, string) The id of the field in {swimlane}. @@ -197,7 +203,7 @@ installed in {sn}. (Optional, object) Mapping for the case comments. `fieldType`:::: -(Required, object) The type of the field in {swimlane}. +(Required, string) The type of the field in {swimlane}. `id`:::: (Required, string) The id of the field in {swimlane}. @@ -212,7 +218,7 @@ installed in {sn}. (Optional, object) Mapping for the case description. `fieldType`:::: -(Required, object) The type of the field in {swimlane}. +(Required, string) The type of the field in {swimlane}. `id`:::: (Required, string) The id of the field in {swimlane}. @@ -227,7 +233,7 @@ installed in {sn}. (Optional, object) Mapping for the name of the alert's rule. `fieldType`:::: -(Required, Object) The type of the field in {swimlane}. +(Required, string) The type of the field in {swimlane}. `id`:::: (Required, string) The id of the field in {swimlane}. @@ -242,7 +248,7 @@ installed in {sn}. (Optional, object) Mapping for the severity. `fieldType`:::: -(Required, object) The type of the field in {swimlane}. +(Required, string) The type of the field in {swimlane}. `id`:::: (Required, string) The id of the field in {swimlane}. diff --git a/docs/api/actions-and-connectors/update.asciidoc b/docs/api/actions-and-connectors/update.asciidoc index 16fb327e61931..b690d3fac995b 100644 --- a/docs/api/actions-and-connectors/update.asciidoc +++ b/docs/api/actions-and-connectors/update.asciidoc @@ -6,6 +6,12 @@ Updates the attributes for a connector. +[NOTE] +==== +For the most up-to-date API details, refer to the +{kib-repo}/tree/{branch}/x-pack/plugins/actions/docs/openapi[open API specification]. For a preview, check out <>. +==== + [[update-connector-api-request]] === {api-request-title} diff --git a/x-pack/plugins/actions/docs/openapi/bundled.json b/x-pack/plugins/actions/docs/openapi/bundled.json index 85c2d1ec66a55..0919fea40668b 100644 --- a/x-pack/plugins/actions/docs/openapi/bundled.json +++ b/x-pack/plugins/actions/docs/openapi/bundled.json @@ -25,6 +25,146 @@ } ], "paths": { + "/s/{spaceId}/api/actions/connector": { + "post": { + "summary": "Creates a connector.", + "operationId": "createConnector", + "description": "You must have `all` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges.\n", + "tags": [ + "connectors" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "title": "Create connector request body properties", + "description": "The properties vary depending on the connector type.", + "oneOf": [ + { + "$ref": "#/components/schemas/create_connector_request_cases_webhook" + }, + { + "$ref": "#/components/schemas/create_connector_request_email" + }, + { + "$ref": "#/components/schemas/create_connector_request_index" + }, + { + "$ref": "#/components/schemas/create_connector_request_jira" + }, + { + "$ref": "#/components/schemas/create_connector_request_opsgenie" + }, + { + "$ref": "#/components/schemas/create_connector_request_pagerduty" + }, + { + "$ref": "#/components/schemas/create_connector_request_resilient" + }, + { + "$ref": "#/components/schemas/create_connector_request_serverlog" + }, + { + "$ref": "#/components/schemas/create_connector_request_servicenow" + }, + { + "$ref": "#/components/schemas/create_connector_request_servicenow_itom" + }, + { + "$ref": "#/components/schemas/create_connector_request_servicenow_sir" + }, + { + "$ref": "#/components/schemas/create_connector_request_slack" + }, + { + "$ref": "#/components/schemas/create_connector_request_swimlane" + }, + { + "$ref": "#/components/schemas/create_connector_request_teams" + }, + { + "$ref": "#/components/schemas/create_connector_request_tines" + }, + { + "$ref": "#/components/schemas/create_connector_request_webhook" + }, + { + "$ref": "#/components/schemas/create_connector_request_xmatters" + } + ], + "discriminator": { + "propertyName": "connector_type_id" + } + }, + "examples": { + "createIndexConnectorRequest": { + "$ref": "#/components/examples/create_index_connector_request" + } + } + } + } + }, + "responses": { + "200": { + "description": "Indicates a successful call.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connector_response_properties" + }, + "examples": { + "createIndexConnectorResponse": { + "$ref": "#/components/examples/create_index_connector_response" + } + } + } + } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "example": 401 + } + } + } + } + } + } + }, + "servers": [ + { + "url": "https://localhost:5601" + } + ] + }, + "servers": [ + { + "url": "https://localhost:5601" + } + ] + }, "/s/{spaceId}/api/actions/connector/{connectorId}": { "get": { "summary": "Retrieves a connector by ID.", @@ -44,52 +184,62 @@ "responses": { "200": { "description": "Indicates a successful call.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connector_response_properties" + }, + "examples": { + "getConnectorResponse": { + "$ref": "#/components/examples/get_connector_response" + } + } + } + } + }, + "401": { + "description": "Authorization information is missing or invalid.", "content": { "application/json": { "schema": { "type": "object", - "required": [ - "connector_type_id", - "id", - "is_deprecated", - "is_preconfigured", - "name" - ], "properties": { - "config": { - "type": "object", - "description": "The configuration for the connector. Configuration properties vary depending on the connector type.", - "additionalProperties": true, - "nullable": true - }, - "connector_type_id": { - "$ref": "#/components/schemas/connector_types" - }, - "id": { + "error": { "type": "string", - "description": "The identifier for the connector.", - "example": "b0766e10-d190-11ec-b04c-776c77d14fca" + "example": "Unauthorized" }, - "is_deprecated": { - "$ref": "#/components/schemas/is_deprecated" + "message": { + "type": "string" }, - "is_missing_secrets": { - "$ref": "#/components/schemas/is_missing_secrets" - }, - "is_preconfigured": { - "$ref": "#/components/schemas/is_preconfigured" + "statusCode": { + "type": "integer", + "example": 401 + } + } + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Not Found" }, - "name": { + "message": { "type": "string", - "description": "The display name for the connector.", - "example": "my-connector" + "example": "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + }, + "statusCode": { + "type": "integer", + "example": 404 } } - }, - "examples": { - "getConnectorResponse": { - "$ref": "#/components/examples/get_connector_response" - } } } } @@ -122,6 +272,205 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "example": 401 + } + } + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Not Found" + }, + "message": { + "type": "string", + "example": "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + }, + "statusCode": { + "type": "integer", + "example": 404 + } + } + } + } + } + } + }, + "servers": [ + { + "url": "https://localhost:5601" + } + ] + }, + "put": { + "summary": "Updates the attributes for a connector.", + "operationId": "updateConnector", + "description": "You must have `all` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges.\n", + "tags": [ + "connectors" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/connector_id" + }, + { + "$ref": "#/components/parameters/space_id" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "title": "Update connector request body properties", + "description": "The properties vary depending on the connector type.", + "oneOf": [ + { + "$ref": "#/components/schemas/update_connector_request_cases_webhook" + }, + { + "$ref": "#/components/schemas/update_connector_request_index" + }, + { + "$ref": "#/components/schemas/update_connector_request_jira" + }, + { + "$ref": "#/components/schemas/update_connector_request_opsgenie" + }, + { + "$ref": "#/components/schemas/update_connector_request_resilient" + }, + { + "$ref": "#/components/schemas/update_connector_request_serverlog" + }, + { + "$ref": "#/components/schemas/update_connector_request_servicenow" + }, + { + "$ref": "#/components/schemas/update_connector_request_servicenow_itom" + }, + { + "$ref": "#/components/schemas/update_connector_request_swimlane" + } + ] + }, + "examples": { + "updateIndexConnectorRequest": { + "$ref": "#/components/examples/update_index_connector_request" + } + } + } + } + }, + "responses": { + "200": { + "description": "Indicates a successful call.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connector_response_properties" + } + } + } + }, + "400": { + "description": "Indicates a bad request.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Bad Request" + }, + "message": { + "type": "string", + "example": "error validating action type config: [index]: expected value of type [string] but got [undefined]" + }, + "statusCode": { + "type": "integer", + "example": 400 + } + } + } + } + } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "example": 401 + } + } + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Not Found" + }, + "message": { + "type": "string", + "example": "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + }, + "statusCode": { + "type": "integer", + "example": 404 + } + } + } + } + } } }, "servers": [ @@ -157,6 +506,8 @@ "schema": { "type": "array", "items": { + "title": "Get connectors response body properties", + "description": "The properties vary for each connector type.", "type": "object", "required": [ "connector_type_id", @@ -211,6 +562,29 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "example": 401 + } + } + } + } + } } }, "servers": [ @@ -252,6 +626,8 @@ "content": { "application/json": { "schema": { + "title": "Get connector types response body properties", + "description": "The properties vary for each connector type.", "type": "array", "items": { "type": "object", @@ -306,6 +682,29 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "example": 401 + } + } + } + } + } } }, "servers": [ @@ -334,15 +733,13 @@ } }, "parameters": { - "connector_id": { - "in": "path", - "name": "connectorId", - "description": "An identifier for the connector.", - "required": true, + "kbn_xsrf": { "schema": { - "type": "string", - "example": "df770e30-8b8b-11ed-a780-3b746c987a81" - } + "type": "string" + }, + "in": "header", + "name": "kbn-xsrf", + "required": true }, "space_id": { "in": "path", @@ -354,17 +751,2176 @@ "example": "default" } }, - "kbn_xsrf": { + "connector_id": { + "in": "path", + "name": "connectorId", + "description": "An identifier for the connector.", + "required": true, "schema": { - "type": "string" - }, - "in": "header", - "name": "kbn-xsrf", - "required": true - } - }, + "type": "string", + "example": "df770e30-8b8b-11ed-a780-3b746c987a81" + } + } + }, "schemas": { + "config_properties_cases_webhook": { + "title": "Connector request properties for Webhook - Case Management connector", + "required": [ + "createIncidentJson", + "createIncidentResponseKey", + "createIncidentUrl", + "getIncidentResponseExternalTitleKey", + "getIncidentUrl", + "updateIncidentJson", + "updateIncidentUrl", + "viewIncidentUrl" + ], + "description": "Defines properties for connectors when type is `.cases-webhook`.", + "type": "object", + "properties": { + "createCommentJson": { + "type": "string", + "description": "A JSON payload sent to the create comment URL to create a case comment. You can use variables to add Kibana Cases data to the payload. The required variable is `case.comment`. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated once the Mustache variables have been placed when the REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass.\n", + "example": { + "body": { + "[object Object]": null + } + } + }, + "createCommentMethod": { + "type": "string", + "description": "The REST API HTTP request method to create a case comment in the third-party system. Valid values are `patch`, `post`, and `put`.\n", + "default": "put", + "enum": [ + "patch", + "post", + "put" + ] + }, + "createCommentUrl": { + "type": "string", + "description": "The REST API URL to create a case comment by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts setting`, add the hostname to the allowed hosts.\n", + "example": "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment" + }, + "createIncidentJson": { + "type": "string", + "description": "A JSON payload sent to the create case URL to create a case. You can use variables to add case data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review.\n", + "example": { + "fields": { + "summary": { + "[object Object]": null + }, + "description": { + "[object Object]": null + }, + "labels": { + "[object Object]": null + } + } + } + }, + "createIncidentMethod": { + "type": "string", + "description": "The REST API HTTP request method to create a case in the third-party system. Valid values are `patch`, `post`, and `put`.\n", + "enum": [ + "patch", + "post", + "put" + ], + "default": "post" + }, + "createIncidentResponseKey": { + "type": "string", + "description": "The JSON key in the create case response that contains the external case ID." + }, + "createIncidentUrl": { + "type": "string", + "description": "The REST API URL to create a case in the third-party system. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts.\n" + }, + "getIncidentResponseExternalTitleKey": { + "type": "string", + "description": "The JSON key in get case response that contains the external case title." + }, + "getIncidentUrl": { + "type": "string", + "description": "The REST API URL to get the case by ID from the third-party system. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. You can use a variable to add the external system ID to the URL. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass.\n", + "example": "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}" + }, + "hasAuth": { + "type": "boolean", + "description": "If true, a username and password for login type authentication must be provided.", + "default": true + }, + "headers": { + "type": "string", + "description": "A set of key-value pairs sent as headers with the request URLs for the create case, update case, get case, and create comment methods.\n" + }, + "updateIncidentJson": { + "type": "string", + "description": "The JSON payload sent to the update case URL to update the case. You can use variables to add Kibana Cases data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review.\n", + "example": { + "fields": { + "summary": { + "[object Object]": null + }, + "description": { + "[object Object]": null + }, + "labels": { + "[object Object]": null + } + } + } + }, + "updateIncidentMethod": { + "type": "string", + "description": "The REST API HTTP request method to update the case in the third-party system. Valid values are `patch`, `post`, and `put`.\n", + "default": "put", + "enum": [ + "patch", + "post", + "put" + ] + }, + "updateIncidentUrl": { + "type": "string", + "description": "The REST API URL to update the case by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts.\n", + "example": "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}}" + }, + "viewIncidentUrl": { + "type": "string", + "description": "The URL to view the case in the external system. You can use variables to add the external system ID or external system title to the URL.\n", + "example": "https://testing-jira.atlassian.net/browse/{{{external.system.title}}}" + } + } + }, + "secrets_properties_cases_webhook": { + "title": "Connector secrets properties for Webhook - Case Management connector", + "type": "object", + "properties": { + "password": { + "type": "string", + "description": "The password for HTTP basic authentication. If `hasAuth` is set to `true`, this property is required." + }, + "user": { + "type": "string", + "description": "The username for HTTP basic authentication. If `hasAuth` is set to `true`, this property is required." + } + } + }, + "create_connector_request_cases_webhook": { + "title": "Create Webhook - Case Managment connector request", + "description": "The Webhook - Case Management connector uses axios to send POST, PUT, and GET requests to a case management RESTful API web service.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_cases_webhook" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".cases-webhook" + ], + "example": ".cases-webhook" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_cases_webhook" + } + } + }, + "config_properties_email": { + "title": "Connector request properties for an email connector", + "description": "Defines properties for connectors when type is `.email`.", + "type": "object", + "additionalProperties": true + }, + "secrets_properties_email": { + "title": "Connector secrets properties for an email connector", + "description": "Defines secrets for connectors when type is `.email`.", + "type": "object", + "additionalProperties": true + }, + "create_connector_request_email": { + "title": "Create email connector request", + "description": "The email connector uses the SMTP protocol to send mail messages, using an integration of Nodemailer. An exception is Microsoft Exchange, which uses HTTP protocol for sending emails, Send mail. Email message text is sent as both plain text and html text.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_email" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".email" + ], + "example": ".email" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_email" + } + } + }, + "config_properties_index": { + "title": "Connector request properties for an index connector", + "required": [ + "index" + ], + "description": "Defines properties for connectors when type is `.index`.", + "type": "object", + "properties": { + "executionTimeField": { + "description": "Specifies a field that will contain the time the alert condition was detected.", + "default": null, + "type": "string", + "nullable": true + }, + "index": { + "description": "The Elasticsearch index to be written to.", + "type": "string" + }, + "refresh": { + "description": "The refresh policy for the write request, which affects when changes are made visible to search. Refer to the refresh setting for Elasticsearch document APIs.\n", + "default": false, + "type": "boolean" + } + } + }, + "create_connector_request_index": { + "title": "Create index connector request", + "description": "The index connector indexes a document into Elasticsearch.", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_index" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".index" + ], + "example": ".index" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + } + } + }, + "config_properties_jira": { + "title": "Connector request properties for a Jira connector", + "required": [ + "apiUrl", + "projectKey" + ], + "description": "Defines properties for connectors when type is `.jira`.", + "type": "object", + "properties": { + "apiUrl": { + "description": "The Jira instance URL.", + "type": "string" + }, + "projectKey": { + "description": "The Jira project key.", + "type": "string" + } + } + }, + "secrets_properties_jira": { + "title": "Connector secrets properties for a Jira connector", + "required": [ + "apiToken", + "email" + ], + "description": "Defines secrets for connectors when type is `.jira`.", + "type": "object", + "properties": { + "apiToken": { + "description": "The Jira API authentication token for HTTP basic authentication.", + "type": "string" + }, + "email": { + "description": "The account email for HTTP Basic authentication.", + "type": "string" + } + } + }, + "create_connector_request_jira": { + "title": "Create Jira connector request", + "description": "The Jira connector uses the REST API v2 to create Jira issues.", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_jira" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".jira" + ], + "example": ".jira" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_jira" + } + } + }, + "config_properties_opsgenie": { + "title": "Connector request properties for an Opsgenie connector", + "required": [ + "apiUrl" + ], + "description": "Defines properties for connectors when type is `.opsgenie`.", + "type": "object", + "properties": { + "apiUrl": { + "description": "The Opsgenie URL. For example, `https://api.opsgenie.com` or `https://api.eu.opsgenie.com`. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts.\n", + "type": "string" + } + } + }, + "secrets_properties_opsgenie": { + "title": "Connector secrets properties for an Opsgenie connector", + "required": [ + "apiKey" + ], + "description": "Defines secrets for connectors when type is `.opsgenie`.", + "type": "object", + "properties": { + "apiKey": { + "description": "The Opsgenie API authentication key for HTTP Basic authentication.", + "type": "string" + } + } + }, + "create_connector_request_opsgenie": { + "title": "Create Opsgenie connector request", + "description": "The Opsgenie connector uses the Opsgenie alert API.", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_opsgenie" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".opsgenie" + ], + "example": ".opsgenie" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_opsgenie" + } + } + }, + "config_properties_pagerduty": { + "title": "Connector request properties for a PagerDuty connector", + "description": "Defines properties for connectors when type is `.pagerduty`.", + "type": "object", + "additionalProperties": true + }, + "secrets_properties_pagerduty": { + "title": "Connector secrets properties for a PagerDuty connector", + "description": "Defines secrets for connectors when type is `.pagerduty`.", + "type": "object", + "additionalProperties": true + }, + "create_connector_request_pagerduty": { + "title": "Create PagerDuty connector request", + "description": "The PagerDuty connector uses the v2 Events API to trigger, acknowledge, and resolve PagerDuty alerts.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_pagerduty" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".pagerduty" + ], + "example": ".pagerduty" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_pagerduty" + } + } + }, + "config_properties_resilient": { + "title": "Connector request properties for a IBM Resilient connector", + "required": [ + "apiUrl", + "orgId" + ], + "description": "Defines properties for connectors when type is `.resilient`.", + "type": "object", + "properties": { + "apiUrl": { + "description": "The IBM Resilient instance URL.", + "type": "string" + }, + "orgId": { + "description": "The IBM Resilient organization ID.", + "type": "string" + } + } + }, + "secrets_properties_resilient": { + "title": "Connector secrets properties for IBM Resilient connector", + "required": [ + "apiKeyId", + "apiKeySecret" + ], + "description": "Defines secrets for connectors when type is `.resilient`.", + "type": "object", + "properties": { + "apiKeyId": { + "type": "string", + "description": "The authentication key ID for HTTP Basic authentication." + }, + "apiKeySecret": { + "type": "string", + "description": "The authentication key secret for HTTP Basic authentication." + } + } + }, + "create_connector_request_resilient": { + "title": "Create IBM Resilient connector request", + "description": "The IBM Resilient connector uses the RESILIENT REST v2 to create IBM Resilient incidents.", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_resilient" + }, + "connector_type_id": { + "description": "The type of connector.", + "type": "string", + "example": ".resilient", + "enum": [ + ".resilient" + ] + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_resilient" + } + } + }, + "create_connector_request_serverlog": { + "title": "Create server log connector request", + "description": "This connector writes an entry to the Kibana server log.", + "type": "object", + "required": [ + "connector_type_id", + "name" + ], + "properties": { + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".server-log" + ], + "example": ".server-log" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + } + } + }, + "config_properties_servicenow": { + "title": "Connector request properties for a ServiceNow ITSM connector", + "required": [ + "apiUrl" + ], + "description": "Defines properties for connectors when type is `.servicenow`.", + "type": "object", + "properties": { + "apiUrl": { + "type": "string", + "description": "The ServiceNow instance URL." + }, + "clientId": { + "description": "The client ID assigned to your OAuth application. This property is required when `isOAuth` is `true`.\n", + "type": "string" + }, + "isOAuth": { + "description": "The type of authentication to use. The default value is false, which means basic authentication is used instead of open authorization (OAuth).\n", + "default": false, + "type": "string" + }, + "jwtKeyId": { + "description": "The key identifier assigned to the JWT verifier map of your OAuth application. This property is required when `isOAuth` is `true`.\n", + "type": "string" + }, + "userIdentifierValue": { + "description": "The identifier to use for OAuth authentication. This identifier should be the user field you selected when you created an OAuth JWT API endpoint for external clients in your ServiceNow instance. For example, if the selected user field is `Email`, the user identifier should be the user's email address. This property is required when `isOAuth` is `true`.\n", + "type": "string" + }, + "usesTableApi": { + "description": "Determines whether the connector uses the Table API or the Import Set API. This property is supported only for ServiceNow ITSM and ServiceNow SecOps connectors. NOTE: If this property is set to `false`, the Elastic application should be installed in ServiceNow.\n", + "default": true, + "type": "boolean" + } + } + }, + "secrets_properties_servicenow": { + "title": "Connector secrets properties for ServiceNow ITOM, ServiceNow ITSM, and ServiceNow SecOps connectors", + "description": "Defines secrets for connectors when type is `.servicenow`, `.servicenow-sir`, or `.servicenow-itom`.", + "type": "object", + "properties": { + "clientSecret": { + "type": "string", + "description": "The client secret assigned to your OAuth application. This property is required when `isOAuth` is `true`." + }, + "password": { + "type": "string", + "description": "The password for HTTP basic authentication. This property is required when `isOAuth` is `false`." + }, + "privateKey": { + "type": "string", + "description": "The RSA private key that you created for use in ServiceNow. This property is required when `isOAuth` is `true`." + }, + "privateKeyPassword": { + "type": "string", + "description": "The password for the RSA private key. This property is required when `isOAuth` is `true` and you set a password on your private key." + }, + "username": { + "type": "string", + "description": "The username for HTTP basic authentication. This property is required when `isOAuth` is `false`." + } + } + }, + "create_connector_request_servicenow": { + "title": "Create ServiceNow ITSM connector request", + "description": "The ServiceNow ITSM connector uses the import set API to create ServiceNow incidents. You can use the connector for rule actions and cases.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".servicenow" + ], + "example": ".servicenow" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_servicenow" + } + } + }, + "config_properties_servicenow_itom": { + "title": "Connector request properties for a ServiceNow ITSM connector", + "required": [ + "apiUrl" + ], + "description": "Defines properties for connectors when type is `.servicenow`.", + "type": "object", + "properties": { + "apiUrl": { + "type": "string", + "description": "The ServiceNow instance URL." + }, + "clientId": { + "description": "The client ID assigned to your OAuth application. This property is required when `isOAuth` is `true`.\n", + "type": "string" + }, + "isOAuth": { + "description": "The type of authentication to use. The default value is false, which means basic authentication is used instead of open authorization (OAuth).\n", + "default": false, + "type": "string" + }, + "jwtKeyId": { + "description": "The key identifier assigned to the JWT verifier map of your OAuth application. This property is required when `isOAuth` is `true`.\n", + "type": "string" + }, + "userIdentifierValue": { + "description": "The identifier to use for OAuth authentication. This identifier should be the user field you selected when you created an OAuth JWT API endpoint for external clients in your ServiceNow instance. For example, if the selected user field is `Email`, the user identifier should be the user's email address. This property is required when `isOAuth` is `true`.\n", + "type": "string" + } + } + }, + "create_connector_request_servicenow_itom": { + "title": "Create ServiceNow ITOM connector request", + "description": "The ServiceNow ITOM connector uses the event API to create ServiceNow events. You can use the connector for rule actions.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow_itom" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".servicenow-itom" + ], + "example": ".servicenow-itom" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_servicenow" + } + } + }, + "create_connector_request_servicenow_sir": { + "title": "Create ServiceNow SecOps connector request", + "description": "The ServiceNow SecOps connector uses the import set API to create ServiceNow security incidents. You can use the connector for rule actions and cases.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".servicenow-sir" + ], + "example": ".servicenow-sir" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_servicenow" + } + } + }, + "secrets_properties_slack": { + "title": "Connector secrets properties for a Slack connector", + "description": "Defines secrets for connectors when type is `.slack`.", + "type": "object", + "additionalProperties": true + }, + "create_connector_request_slack": { + "title": "Create Slack connector request", + "description": "The Slack connector uses Slack Incoming Webhooks.", + "type": "object", + "required": [ + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".slack" + ], + "example": ".slack" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_slack" + } + } + }, + "config_properties_swimlane": { + "title": "Connector request properties for a Swimlane connector", + "required": [ + "apiUrl", + "appId", + "connectorType" + ], + "description": "Defines properties for connectors when type is `.swimlane`.", + "type": "object", + "properties": { + "apiUrl": { + "description": "The Swimlane instance URL.", + "type": "string" + }, + "appId": { + "description": "The Swimlane application ID.", + "type": "string" + }, + "connectorType": { + "description": "The type of connector. Valid values are `all`, `alerts`, and `cases`.", + "type": "string", + "enum": [ + "all", + "alerts", + "cases" + ] + }, + "mappings": { + "title": "Connector mappings properties for a Swimlane connector", + "description": "The field mapping.", + "type": "object", + "properties": { + "alertIdConfig": { + "title": "Alert identifier mapping", + "description": "Mapping for the alert ID.", + "type": "object", + "required": [ + "fieldType", + "id", + "key", + "name" + ], + "properties": { + "fieldType": { + "type": "string", + "description": "The type of field in Swimlane." + }, + "id": { + "type": "string", + "description": "The identifier for the field in Swimlane." + }, + "key": { + "type": "string", + "description": "The key for the field in Swimlane." + }, + "name": { + "type": "string", + "description": "The name of the field in Swimlane." + } + } + }, + "caseIdConfig": { + "title": "Case identifier mapping", + "description": "Mapping for the case ID.", + "type": "object", + "required": [ + "fieldType", + "id", + "key", + "name" + ], + "properties": { + "fieldType": { + "type": "string", + "description": "The type of field in Swimlane." + }, + "id": { + "type": "string", + "description": "The identifier for the field in Swimlane." + }, + "key": { + "type": "string", + "description": "The key for the field in Swimlane." + }, + "name": { + "type": "string", + "description": "The name of the field in Swimlane." + } + } + }, + "caseNameConfig": { + "title": "Case name mapping", + "description": "Mapping for the case name.", + "type": "object", + "required": [ + "fieldType", + "id", + "key", + "name" + ], + "properties": { + "fieldType": { + "type": "string", + "description": "The type of field in Swimlane." + }, + "id": { + "type": "string", + "description": "The identifier for the field in Swimlane." + }, + "key": { + "type": "string", + "description": "The key for the field in Swimlane." + }, + "name": { + "type": "string", + "description": "The name of the field in Swimlane." + } + } + }, + "commentsConfig": { + "title": "Case comment mapping", + "description": "Mapping for the case comments.", + "type": "object", + "required": [ + "fieldType", + "id", + "key", + "name" + ], + "properties": { + "fieldType": { + "type": "string", + "description": "The type of field in Swimlane." + }, + "id": { + "type": "string", + "description": "The identifier for the field in Swimlane." + }, + "key": { + "type": "string", + "description": "The key for the field in Swimlane." + }, + "name": { + "type": "string", + "description": "The name of the field in Swimlane." + } + } + }, + "descriptionConfig": { + "title": "Case description mapping", + "description": "Mapping for the case description.", + "type": "object", + "required": [ + "fieldType", + "id", + "key", + "name" + ], + "properties": { + "fieldType": { + "type": "string", + "description": "The type of field in Swimlane." + }, + "id": { + "type": "string", + "description": "The identifier for the field in Swimlane." + }, + "key": { + "type": "string", + "description": "The key for the field in Swimlane." + }, + "name": { + "type": "string", + "description": "The name of the field in Swimlane." + } + } + }, + "ruleNameConfig": { + "title": "Rule name mapping", + "description": "Mapping for the name of the alert's rule.", + "type": "object", + "required": [ + "fieldType", + "id", + "key", + "name" + ], + "properties": { + "fieldType": { + "type": "string", + "description": "The type of field in Swimlane." + }, + "id": { + "type": "string", + "description": "The identifier for the field in Swimlane." + }, + "key": { + "type": "string", + "description": "The key for the field in Swimlane." + }, + "name": { + "type": "string", + "description": "The name of the field in Swimlane." + } + } + }, + "severityConfig": { + "title": "Severity mapping", + "description": "Mapping for the severity.", + "type": "object", + "required": [ + "fieldType", + "id", + "key", + "name" + ], + "properties": { + "fieldType": { + "type": "string", + "description": "The type of field in Swimlane." + }, + "id": { + "type": "string", + "description": "The identifier for the field in Swimlane." + }, + "key": { + "type": "string", + "description": "The key for the field in Swimlane." + }, + "name": { + "type": "string", + "description": "The name of the field in Swimlane." + } + } + } + } + } + } + }, + "secrets_properties_swimlane": { + "title": "Connector secrets properties for a Swimlane connector", + "description": "Defines secrets for connectors when type is `.swimlane`.", + "type": "object", + "properties": { + "apiToken": { + "description": "Swimlane API authentication token.", + "type": "string" + } + } + }, + "create_connector_request_swimlane": { + "title": "Create Swimlane connector request", + "description": "The Swimlane connector uses the Swimlane REST API to create Swimlane records.", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_swimlane" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".swimlane" + ], + "example": ".swimlane" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_swimlane" + } + } + }, + "secrets_properties_teams": { + "title": "Connector secrets properties for a Microsoft Teams connector", + "description": "Defines secrets for connectors when type is `.teams`.", + "type": "object", + "additionalProperties": true + }, + "create_connector_request_teams": { + "title": "Create Microsoft Teams connector request", + "description": "The Microsoft Teams connector uses Incoming Webhooks.", + "type": "object", + "required": [ + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".teams" + ], + "example": ".teams" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_teams" + } + } + }, + "config_properties_tines": { + "title": "Connector request properties for a Tines connector", + "description": "Defines properties for connectors when type is `.tines`.", + "type": "object", + "additionalProperties": true + }, + "secrets_properties_tines": { + "title": "Connector secrets properties for a Tines connector", + "description": "Defines secrets for connectors when type is `.tines`.", + "type": "object", + "additionalProperties": true + }, + "create_connector_request_tines": { + "title": "Create Tines connector request", + "description": "The Tines connector uses Tines Webhook actions to send events via POST request.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_tines" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".tines" + ], + "example": ".tines" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_tines" + } + } + }, + "config_properties_webhook": { + "title": "Connector request properties for a Webhook connector", + "description": "Defines properties for connectors when type is `.webhook`.", + "type": "object", + "additionalProperties": true + }, + "secrets_properties_webhook": { + "title": "Connector secrets properties for a Webhook connector", + "description": "Defines secrets for connectors when type is `.webhook`.", + "type": "object", + "additionalProperties": true + }, + "create_connector_request_webhook": { + "title": "Create Webhook connector request", + "description": "The Webhook connector uses axios to send a POST or PUT request to a web service.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_webhook" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".webhook" + ], + "example": ".webhook" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_webhook" + } + } + }, + "config_properties_xmatters": { + "title": "Connector request properties for a xMatters connector", + "description": "Defines properties for connectors when type is `.xmatters`.", + "type": "object", + "additionalProperties": true + }, + "secrets_properties_xmatters": { + "title": "Connector secrets properties for an xMatters connector", + "description": "Defines secrets for connectors when type is `.xmatters`.", + "type": "object", + "additionalProperties": true + }, + "create_connector_request_xmatters": { + "title": "Create xMatters connector request", + "description": "The xMatters connector uses the xMatters Workflow for Elastic to send actionable alerts to on-call xMatters resources.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_xmatters" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".xmatters" + ], + "example": ".xmatters" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_xmatters" + } + } + }, + "is_deprecated": { + "type": "boolean", + "description": "Indicates whether the connector type is deprecated.", + "example": false + }, + "is_missing_secrets": { + "type": "boolean", + "description": "Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.", + "example": false + }, + "is_preconfigured": { + "type": "boolean", + "description": "Indicates whether it is a preconfigured connector. If true, the `config` and `is_missing_secrets` properties are omitted from the response.", + "example": false + }, + "connector_response_properties_cases_webhook": { + "title": "Connector request properties for a Webhook - Case Management connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_cases_webhook" + }, + "connector_type_id": { + "description": "The type of connector.", + "type": "string", + "enum": [ + ".cases-webhook" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_email": { + "title": "Connector response properties for an email connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_email" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".email" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_index": { + "title": "Connector response properties for an index connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_index" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".index" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_jira": { + "title": "Connector response properties for a Jira connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_jira" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".jira" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_opsgenie": { + "title": "Connector response properties for an Opsgenie connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_opsgenie" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".opsgenie" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_pagerduty": { + "title": "Connector response properties for a PagerDuty connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_pagerduty" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".pagerduty" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_resilient": { + "title": "Connector response properties for a IBM Resilient connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_resilient" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".resilient" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_serverlog": { + "title": "Connector response properties for a server log connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "type": "object", + "nullable": true + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".server-log" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_servicenow": { + "title": "Connector response properties for a ServiceNow ITSM connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".servicenow" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_servicenow_itom": { + "title": "Connector response properties for a ServiceNow ITOM connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow_itom" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".servicenow-itom" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_servicenow_sir": { + "title": "Connector response properties for a ServiceNow SecOps connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".servicenow-sir" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_slack": { + "title": "Connector response properties for a Slack connector", + "type": "object", + "required": [ + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".slack" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_swimlane": { + "title": "Connector response properties for a Swimlane connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_swimlane" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".swimlane" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_teams": { + "title": "Connector response properties for a Microsoft Teams connector", + "type": "object", + "required": [ + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".teams" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_tines": { + "title": "Connector response properties for a Tines connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_tines" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".tines" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_webhook": { + "title": "Connector response properties for a Webhook connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_webhook" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".webhook" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_xmatters": { + "title": "Connector response properties for an xMatters connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_xmatters" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".xmatters" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties": { + "title": "Connector response properties", + "description": "The properties vary depending on the connector type.", + "oneOf": [ + { + "$ref": "#/components/schemas/connector_response_properties_cases_webhook" + }, + { + "$ref": "#/components/schemas/connector_response_properties_email" + }, + { + "$ref": "#/components/schemas/connector_response_properties_index" + }, + { + "$ref": "#/components/schemas/connector_response_properties_jira" + }, + { + "$ref": "#/components/schemas/connector_response_properties_opsgenie" + }, + { + "$ref": "#/components/schemas/connector_response_properties_pagerduty" + }, + { + "$ref": "#/components/schemas/connector_response_properties_resilient" + }, + { + "$ref": "#/components/schemas/connector_response_properties_serverlog" + }, + { + "$ref": "#/components/schemas/connector_response_properties_servicenow" + }, + { + "$ref": "#/components/schemas/connector_response_properties_servicenow_itom" + }, + { + "$ref": "#/components/schemas/connector_response_properties_servicenow_sir" + }, + { + "$ref": "#/components/schemas/connector_response_properties_slack" + }, + { + "$ref": "#/components/schemas/connector_response_properties_swimlane" + }, + { + "$ref": "#/components/schemas/connector_response_properties_teams" + }, + { + "$ref": "#/components/schemas/connector_response_properties_tines" + }, + { + "$ref": "#/components/schemas/connector_response_properties_webhook" + }, + { + "$ref": "#/components/schemas/connector_response_properties_xmatters" + } + ], + "discriminator": { + "propertyName": "connector_type_id" + } + }, + "update_connector_request_cases_webhook": { + "title": "Update Webhook - Case Managment connector request", + "type": "object", + "required": [ + "config", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_cases_webhook" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_cases_webhook" + } + } + }, + "update_connector_request_index": { + "title": "Update index connector request", + "type": "object", + "required": [ + "config", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_index" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "update_connector_request_jira": { + "title": "Update Jira connector request", + "type": "object", + "required": [ + "config", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_jira" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_jira" + } + } + }, + "update_connector_request_opsgenie": { + "title": "Update Opsgenie connector request", + "type": "object", + "required": [ + "config", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_opsgenie" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_opsgenie" + } + } + }, + "update_connector_request_resilient": { + "title": "Update IBM Resilient connector request", + "type": "object", + "required": [ + "config", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_resilient" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_resilient" + } + } + }, + "update_connector_request_serverlog": { + "title": "Update server log connector request", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "update_connector_request_servicenow": { + "title": "Update ServiceNow ITSM connector or ServiceNow SecOps request", + "type": "object", + "required": [ + "config", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_servicenow" + } + } + }, + "update_connector_request_servicenow_itom": { + "title": "Create ServiceNow ITOM connector request", + "type": "object", + "required": [ + "config", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow_itom" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_servicenow" + } + } + }, + "update_connector_request_swimlane": { + "title": "Update Swimlane connector request", + "type": "object", + "required": [ + "config", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_swimlane" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_swimlane" + } + } + }, "connector_types": { + "title": "Connector types", "type": "string", "description": "The type of connector. For example, `.email`, `.index`, `.jira`, `.opsgenie`, or `.server-log`.", "enum": [ @@ -388,21 +2944,6 @@ ], "example": ".server-log" }, - "is_deprecated": { - "type": "boolean", - "description": "Indicates whether the connector type is deprecated.", - "example": false - }, - "is_missing_secrets": { - "type": "boolean", - "description": "Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.", - "example": false - }, - "is_preconfigured": { - "type": "boolean", - "description": "Indicates whether it is a preconfigured connector. If true, the `config` and `is_missing_secrets` properties are omitted from the response.", - "example": false - }, "features": { "type": "string", "description": "The feature that uses the connector. Valid values are `alerting`, `cases`, `uptime`, and `siem`.\n", @@ -415,6 +2956,32 @@ } }, "examples": { + "create_index_connector_request": { + "summary": "Create an index connector.", + "value": { + "name": "my-connector", + "connector_type_id": ".index", + "config": { + "index": "test-index" + } + } + }, + "create_index_connector_response": { + "summary": "A new index connector.", + "value": { + "id": "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad", + "connector_type_id": ".index", + "name": "my-connector", + "config": { + "index": "test-index", + "refresh": false, + "executionTimeField": null + }, + "is_preconfigured": false, + "is_deprecated": false, + "is_missing_secrets": false + } + }, "get_connector_response": { "summary": "A list of connector types", "value": { @@ -427,6 +2994,15 @@ "is_missing_secrets": false } }, + "update_index_connector_request": { + "summary": "Update an index connector.", + "value": { + "name": "updated-connector", + "config": { + "index": "updated-index" + } + } + }, "get_connectors_response": { "summary": "A list of connectors", "value": [ diff --git a/x-pack/plugins/actions/docs/openapi/bundled.yaml b/x-pack/plugins/actions/docs/openapi/bundled.yaml index 8d52047d1181b..1ffc0dc5da1eb 100644 --- a/x-pack/plugins/actions/docs/openapi/bundled.yaml +++ b/x-pack/plugins/actions/docs/openapi/bundled.yaml @@ -15,6 +15,76 @@ servers: - url: http://localhost:5601 description: local paths: + /s/{spaceId}/api/actions/connector: + post: + summary: Creates a connector. + operationId: createConnector + description: | + You must have `all` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges. + tags: + - connectors + parameters: + - $ref: '#/components/parameters/kbn_xsrf' + - $ref: '#/components/parameters/space_id' + requestBody: + required: true + content: + application/json: + schema: + title: Create connector request body properties + description: The properties vary depending on the connector type. + oneOf: + - $ref: '#/components/schemas/create_connector_request_cases_webhook' + - $ref: '#/components/schemas/create_connector_request_email' + - $ref: '#/components/schemas/create_connector_request_index' + - $ref: '#/components/schemas/create_connector_request_jira' + - $ref: '#/components/schemas/create_connector_request_opsgenie' + - $ref: '#/components/schemas/create_connector_request_pagerduty' + - $ref: '#/components/schemas/create_connector_request_resilient' + - $ref: '#/components/schemas/create_connector_request_serverlog' + - $ref: '#/components/schemas/create_connector_request_servicenow' + - $ref: '#/components/schemas/create_connector_request_servicenow_itom' + - $ref: '#/components/schemas/create_connector_request_servicenow_sir' + - $ref: '#/components/schemas/create_connector_request_slack' + - $ref: '#/components/schemas/create_connector_request_swimlane' + - $ref: '#/components/schemas/create_connector_request_teams' + - $ref: '#/components/schemas/create_connector_request_tines' + - $ref: '#/components/schemas/create_connector_request_webhook' + - $ref: '#/components/schemas/create_connector_request_xmatters' + discriminator: + propertyName: connector_type_id + examples: + createIndexConnectorRequest: + $ref: '#/components/examples/create_index_connector_request' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + $ref: '#/components/schemas/connector_response_properties' + examples: + createIndexConnectorResponse: + $ref: '#/components/examples/create_index_connector_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + servers: + - url: https://localhost:5601 + servers: + - url: https://localhost:5601 /s/{spaceId}/api/actions/connector/{connectorId}: get: summary: Retrieves a connector by ID. @@ -29,41 +99,44 @@ paths: responses: '200': description: Indicates a successful call. + content: + application/json: + schema: + $ref: '#/components/schemas/connector_response_properties' + examples: + getConnectorResponse: + $ref: '#/components/examples/get_connector_response' + '401': + description: Authorization information is missing or invalid. content: application/json: schema: type: object - required: - - connector_type_id - - id - - is_deprecated - - is_preconfigured - - name properties: - config: - type: object - description: The configuration for the connector. Configuration properties vary depending on the connector type. - additionalProperties: true - nullable: true - connector_type_id: - $ref: '#/components/schemas/connector_types' - id: + error: type: string - description: The identifier for the connector. - example: b0766e10-d190-11ec-b04c-776c77d14fca - is_deprecated: - $ref: '#/components/schemas/is_deprecated' - is_missing_secrets: - $ref: '#/components/schemas/is_missing_secrets' - is_preconfigured: - $ref: '#/components/schemas/is_preconfigured' - name: + example: Unauthorized + message: type: string - description: The display name for the connector. - example: my-connector - examples: - getConnectorResponse: - $ref: '#/components/examples/get_connector_response' + statusCode: + type: integer + example: 401 + '404': + description: Object is not found. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Not Found + message: + type: string + example: Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found + statusCode: + type: integer + example: 404 servers: - url: https://localhost:5601 delete: @@ -80,6 +153,124 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + '404': + description: Object is not found. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Not Found + message: + type: string + example: Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found + statusCode: + type: integer + example: 404 + servers: + - url: https://localhost:5601 + put: + summary: Updates the attributes for a connector. + operationId: updateConnector + description: | + You must have `all` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges. + tags: + - connectors + parameters: + - $ref: '#/components/parameters/kbn_xsrf' + - $ref: '#/components/parameters/connector_id' + - $ref: '#/components/parameters/space_id' + requestBody: + required: true + content: + application/json: + schema: + title: Update connector request body properties + description: The properties vary depending on the connector type. + oneOf: + - $ref: '#/components/schemas/update_connector_request_cases_webhook' + - $ref: '#/components/schemas/update_connector_request_index' + - $ref: '#/components/schemas/update_connector_request_jira' + - $ref: '#/components/schemas/update_connector_request_opsgenie' + - $ref: '#/components/schemas/update_connector_request_resilient' + - $ref: '#/components/schemas/update_connector_request_serverlog' + - $ref: '#/components/schemas/update_connector_request_servicenow' + - $ref: '#/components/schemas/update_connector_request_servicenow_itom' + - $ref: '#/components/schemas/update_connector_request_swimlane' + examples: + updateIndexConnectorRequest: + $ref: '#/components/examples/update_index_connector_request' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + $ref: '#/components/schemas/connector_response_properties' + '400': + description: Indicates a bad request. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Bad Request + message: + type: string + example: 'error validating action type config: [index]: expected value of type [string] but got [undefined]' + statusCode: + type: integer + example: 400 + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + '404': + description: Object is not found. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Not Found + message: + type: string + example: Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found + statusCode: + type: integer + example: 404 servers: - url: https://localhost:5601 servers: @@ -102,6 +293,8 @@ paths: schema: type: array items: + title: Get connectors response body properties + description: The properties vary for each connector type. type: object required: - connector_type_id @@ -140,6 +333,21 @@ paths: examples: getConnectorsResponse: $ref: '#/components/examples/get_connectors_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 servers: - url: https://localhost:5601 servers: @@ -165,6 +373,8 @@ paths: content: application/json: schema: + title: Get connector types response body properties + description: The properties vary for each connector type. type: array items: type: object @@ -203,6 +413,21 @@ paths: examples: getConnectorTypesResponse: $ref: '#/components/examples/get_connector_types_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 servers: - url: https://localhost:5601 servers: @@ -217,14 +442,12 @@ components: in: header name: ApiKey parameters: - connector_id: - in: path - name: connectorId - description: An identifier for the connector. - required: true + kbn_xsrf: schema: type: string - example: df770e30-8b8b-11ed-a780-3b746c987a81 + in: header + name: kbn-xsrf + required: true space_id: in: path name: spaceId @@ -233,14 +456,1630 @@ components: schema: type: string example: default - kbn_xsrf: + connector_id: + in: path + name: connectorId + description: An identifier for the connector. + required: true schema: type: string - in: header - name: kbn-xsrf - required: true + example: df770e30-8b8b-11ed-a780-3b746c987a81 schemas: + config_properties_cases_webhook: + title: Connector request properties for Webhook - Case Management connector + required: + - createIncidentJson + - createIncidentResponseKey + - createIncidentUrl + - getIncidentResponseExternalTitleKey + - getIncidentUrl + - updateIncidentJson + - updateIncidentUrl + - viewIncidentUrl + description: Defines properties for connectors when type is `.cases-webhook`. + type: object + properties: + createCommentJson: + type: string + description: | + A JSON payload sent to the create comment URL to create a case comment. You can use variables to add Kibana Cases data to the payload. The required variable is `case.comment`. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated once the Mustache variables have been placed when the REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass. + example: + body: + '[object Object]': null + createCommentMethod: + type: string + description: | + The REST API HTTP request method to create a case comment in the third-party system. Valid values are `patch`, `post`, and `put`. + default: put + enum: + - patch + - post + - put + createCommentUrl: + type: string + description: | + The REST API URL to create a case comment by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts setting`, add the hostname to the allowed hosts. + example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment + createIncidentJson: + type: string + description: | + A JSON payload sent to the create case URL to create a case. You can use variables to add case data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review. + example: + fields: + summary: + '[object Object]': null + description: + '[object Object]': null + labels: + '[object Object]': null + createIncidentMethod: + type: string + description: | + The REST API HTTP request method to create a case in the third-party system. Valid values are `patch`, `post`, and `put`. + enum: + - patch + - post + - put + default: post + createIncidentResponseKey: + type: string + description: The JSON key in the create case response that contains the external case ID. + createIncidentUrl: + type: string + description: | + The REST API URL to create a case in the third-party system. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. + getIncidentResponseExternalTitleKey: + type: string + description: The JSON key in get case response that contains the external case title. + getIncidentUrl: + type: string + description: | + The REST API URL to get the case by ID from the third-party system. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. You can use a variable to add the external system ID to the URL. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass. + example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}} + hasAuth: + type: boolean + description: If true, a username and password for login type authentication must be provided. + default: true + headers: + type: string + description: | + A set of key-value pairs sent as headers with the request URLs for the create case, update case, get case, and create comment methods. + updateIncidentJson: + type: string + description: | + The JSON payload sent to the update case URL to update the case. You can use variables to add Kibana Cases data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review. + example: + fields: + summary: + '[object Object]': null + description: + '[object Object]': null + labels: + '[object Object]': null + updateIncidentMethod: + type: string + description: | + The REST API HTTP request method to update the case in the third-party system. Valid values are `patch`, `post`, and `put`. + default: put + enum: + - patch + - post + - put + updateIncidentUrl: + type: string + description: | + The REST API URL to update the case by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. + example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}} + viewIncidentUrl: + type: string + description: | + The URL to view the case in the external system. You can use variables to add the external system ID or external system title to the URL. + example: https://testing-jira.atlassian.net/browse/{{{external.system.title}}} + secrets_properties_cases_webhook: + title: Connector secrets properties for Webhook - Case Management connector + type: object + properties: + password: + type: string + description: The password for HTTP basic authentication. If `hasAuth` is set to `true`, this property is required. + user: + type: string + description: The username for HTTP basic authentication. If `hasAuth` is set to `true`, this property is required. + create_connector_request_cases_webhook: + title: Create Webhook - Case Managment connector request + description: | + The Webhook - Case Management connector uses axios to send POST, PUT, and GET requests to a case management RESTful API web service. + type: object + required: + - config + - connector_type_id + - name + properties: + config: + $ref: '#/components/schemas/config_properties_cases_webhook' + connector_type_id: + type: string + description: The type of connector. + enum: + - .cases-webhook + example: .cases-webhook + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_cases_webhook' + config_properties_email: + title: Connector request properties for an email connector + description: Defines properties for connectors when type is `.email`. + type: object + additionalProperties: true + secrets_properties_email: + title: Connector secrets properties for an email connector + description: Defines secrets for connectors when type is `.email`. + type: object + additionalProperties: true + create_connector_request_email: + title: Create email connector request + description: | + The email connector uses the SMTP protocol to send mail messages, using an integration of Nodemailer. An exception is Microsoft Exchange, which uses HTTP protocol for sending emails, Send mail. Email message text is sent as both plain text and html text. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_email' + connector_type_id: + type: string + description: The type of connector. + enum: + - .email + example: .email + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_email' + config_properties_index: + title: Connector request properties for an index connector + required: + - index + description: Defines properties for connectors when type is `.index`. + type: object + properties: + executionTimeField: + description: Specifies a field that will contain the time the alert condition was detected. + default: null + type: string + nullable: true + index: + description: The Elasticsearch index to be written to. + type: string + refresh: + description: | + The refresh policy for the write request, which affects when changes are made visible to search. Refer to the refresh setting for Elasticsearch document APIs. + default: false + type: boolean + create_connector_request_index: + title: Create index connector request + description: The index connector indexes a document into Elasticsearch. + type: object + required: + - config + - connector_type_id + - name + properties: + config: + $ref: '#/components/schemas/config_properties_index' + connector_type_id: + type: string + description: The type of connector. + enum: + - .index + example: .index + name: + type: string + description: The display name for the connector. + example: my-connector + config_properties_jira: + title: Connector request properties for a Jira connector + required: + - apiUrl + - projectKey + description: Defines properties for connectors when type is `.jira`. + type: object + properties: + apiUrl: + description: The Jira instance URL. + type: string + projectKey: + description: The Jira project key. + type: string + secrets_properties_jira: + title: Connector secrets properties for a Jira connector + required: + - apiToken + - email + description: Defines secrets for connectors when type is `.jira`. + type: object + properties: + apiToken: + description: The Jira API authentication token for HTTP basic authentication. + type: string + email: + description: The account email for HTTP Basic authentication. + type: string + create_connector_request_jira: + title: Create Jira connector request + description: The Jira connector uses the REST API v2 to create Jira issues. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_jira' + connector_type_id: + type: string + description: The type of connector. + enum: + - .jira + example: .jira + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_jira' + config_properties_opsgenie: + title: Connector request properties for an Opsgenie connector + required: + - apiUrl + description: Defines properties for connectors when type is `.opsgenie`. + type: object + properties: + apiUrl: + description: | + The Opsgenie URL. For example, `https://api.opsgenie.com` or `https://api.eu.opsgenie.com`. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. + type: string + secrets_properties_opsgenie: + title: Connector secrets properties for an Opsgenie connector + required: + - apiKey + description: Defines secrets for connectors when type is `.opsgenie`. + type: object + properties: + apiKey: + description: The Opsgenie API authentication key for HTTP Basic authentication. + type: string + create_connector_request_opsgenie: + title: Create Opsgenie connector request + description: The Opsgenie connector uses the Opsgenie alert API. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_opsgenie' + connector_type_id: + type: string + description: The type of connector. + enum: + - .opsgenie + example: .opsgenie + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_opsgenie' + config_properties_pagerduty: + title: Connector request properties for a PagerDuty connector + description: Defines properties for connectors when type is `.pagerduty`. + type: object + additionalProperties: true + secrets_properties_pagerduty: + title: Connector secrets properties for a PagerDuty connector + description: Defines secrets for connectors when type is `.pagerduty`. + type: object + additionalProperties: true + create_connector_request_pagerduty: + title: Create PagerDuty connector request + description: | + The PagerDuty connector uses the v2 Events API to trigger, acknowledge, and resolve PagerDuty alerts. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_pagerduty' + connector_type_id: + type: string + description: The type of connector. + enum: + - .pagerduty + example: .pagerduty + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_pagerduty' + config_properties_resilient: + title: Connector request properties for a IBM Resilient connector + required: + - apiUrl + - orgId + description: Defines properties for connectors when type is `.resilient`. + type: object + properties: + apiUrl: + description: The IBM Resilient instance URL. + type: string + orgId: + description: The IBM Resilient organization ID. + type: string + secrets_properties_resilient: + title: Connector secrets properties for IBM Resilient connector + required: + - apiKeyId + - apiKeySecret + description: Defines secrets for connectors when type is `.resilient`. + type: object + properties: + apiKeyId: + type: string + description: The authentication key ID for HTTP Basic authentication. + apiKeySecret: + type: string + description: The authentication key secret for HTTP Basic authentication. + create_connector_request_resilient: + title: Create IBM Resilient connector request + description: The IBM Resilient connector uses the RESILIENT REST v2 to create IBM Resilient incidents. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_resilient' + connector_type_id: + description: The type of connector. + type: string + example: .resilient + enum: + - .resilient + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_resilient' + create_connector_request_serverlog: + title: Create server log connector request + description: This connector writes an entry to the Kibana server log. + type: object + required: + - connector_type_id + - name + properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .server-log + example: .server-log + name: + type: string + description: The display name for the connector. + example: my-connector + config_properties_servicenow: + title: Connector request properties for a ServiceNow ITSM connector + required: + - apiUrl + description: Defines properties for connectors when type is `.servicenow`. + type: object + properties: + apiUrl: + type: string + description: The ServiceNow instance URL. + clientId: + description: | + The client ID assigned to your OAuth application. This property is required when `isOAuth` is `true`. + type: string + isOAuth: + description: | + The type of authentication to use. The default value is false, which means basic authentication is used instead of open authorization (OAuth). + default: false + type: string + jwtKeyId: + description: | + The key identifier assigned to the JWT verifier map of your OAuth application. This property is required when `isOAuth` is `true`. + type: string + userIdentifierValue: + description: | + The identifier to use for OAuth authentication. This identifier should be the user field you selected when you created an OAuth JWT API endpoint for external clients in your ServiceNow instance. For example, if the selected user field is `Email`, the user identifier should be the user's email address. This property is required when `isOAuth` is `true`. + type: string + usesTableApi: + description: | + Determines whether the connector uses the Table API or the Import Set API. This property is supported only for ServiceNow ITSM and ServiceNow SecOps connectors. NOTE: If this property is set to `false`, the Elastic application should be installed in ServiceNow. + default: true + type: boolean + secrets_properties_servicenow: + title: Connector secrets properties for ServiceNow ITOM, ServiceNow ITSM, and ServiceNow SecOps connectors + description: Defines secrets for connectors when type is `.servicenow`, `.servicenow-sir`, or `.servicenow-itom`. + type: object + properties: + clientSecret: + type: string + description: The client secret assigned to your OAuth application. This property is required when `isOAuth` is `true`. + password: + type: string + description: The password for HTTP basic authentication. This property is required when `isOAuth` is `false`. + privateKey: + type: string + description: The RSA private key that you created for use in ServiceNow. This property is required when `isOAuth` is `true`. + privateKeyPassword: + type: string + description: The password for the RSA private key. This property is required when `isOAuth` is `true` and you set a password on your private key. + username: + type: string + description: The username for HTTP basic authentication. This property is required when `isOAuth` is `false`. + create_connector_request_servicenow: + title: Create ServiceNow ITSM connector request + description: | + The ServiceNow ITSM connector uses the import set API to create ServiceNow incidents. You can use the connector for rule actions and cases. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow + example: .servicenow + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_servicenow' + config_properties_servicenow_itom: + title: Connector request properties for a ServiceNow ITSM connector + required: + - apiUrl + description: Defines properties for connectors when type is `.servicenow`. + type: object + properties: + apiUrl: + type: string + description: The ServiceNow instance URL. + clientId: + description: | + The client ID assigned to your OAuth application. This property is required when `isOAuth` is `true`. + type: string + isOAuth: + description: | + The type of authentication to use. The default value is false, which means basic authentication is used instead of open authorization (OAuth). + default: false + type: string + jwtKeyId: + description: | + The key identifier assigned to the JWT verifier map of your OAuth application. This property is required when `isOAuth` is `true`. + type: string + userIdentifierValue: + description: | + The identifier to use for OAuth authentication. This identifier should be the user field you selected when you created an OAuth JWT API endpoint for external clients in your ServiceNow instance. For example, if the selected user field is `Email`, the user identifier should be the user's email address. This property is required when `isOAuth` is `true`. + type: string + create_connector_request_servicenow_itom: + title: Create ServiceNow ITOM connector request + description: | + The ServiceNow ITOM connector uses the event API to create ServiceNow events. You can use the connector for rule actions. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow_itom' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-itom + example: .servicenow-itom + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_servicenow' + create_connector_request_servicenow_sir: + title: Create ServiceNow SecOps connector request + description: | + The ServiceNow SecOps connector uses the import set API to create ServiceNow security incidents. You can use the connector for rule actions and cases. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-sir + example: .servicenow-sir + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_servicenow' + secrets_properties_slack: + title: Connector secrets properties for a Slack connector + description: Defines secrets for connectors when type is `.slack`. + type: object + additionalProperties: true + create_connector_request_slack: + title: Create Slack connector request + description: The Slack connector uses Slack Incoming Webhooks. + type: object + required: + - connector_type_id + - name + - secrets + properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .slack + example: .slack + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_slack' + config_properties_swimlane: + title: Connector request properties for a Swimlane connector + required: + - apiUrl + - appId + - connectorType + description: Defines properties for connectors when type is `.swimlane`. + type: object + properties: + apiUrl: + description: The Swimlane instance URL. + type: string + appId: + description: The Swimlane application ID. + type: string + connectorType: + description: The type of connector. Valid values are `all`, `alerts`, and `cases`. + type: string + enum: + - all + - alerts + - cases + mappings: + title: Connector mappings properties for a Swimlane connector + description: The field mapping. + type: object + properties: + alertIdConfig: + title: Alert identifier mapping + description: Mapping for the alert ID. + type: object + required: + - fieldType + - id + - key + - name + properties: + fieldType: + type: string + description: The type of field in Swimlane. + id: + type: string + description: The identifier for the field in Swimlane. + key: + type: string + description: The key for the field in Swimlane. + name: + type: string + description: The name of the field in Swimlane. + caseIdConfig: + title: Case identifier mapping + description: Mapping for the case ID. + type: object + required: + - fieldType + - id + - key + - name + properties: + fieldType: + type: string + description: The type of field in Swimlane. + id: + type: string + description: The identifier for the field in Swimlane. + key: + type: string + description: The key for the field in Swimlane. + name: + type: string + description: The name of the field in Swimlane. + caseNameConfig: + title: Case name mapping + description: Mapping for the case name. + type: object + required: + - fieldType + - id + - key + - name + properties: + fieldType: + type: string + description: The type of field in Swimlane. + id: + type: string + description: The identifier for the field in Swimlane. + key: + type: string + description: The key for the field in Swimlane. + name: + type: string + description: The name of the field in Swimlane. + commentsConfig: + title: Case comment mapping + description: Mapping for the case comments. + type: object + required: + - fieldType + - id + - key + - name + properties: + fieldType: + type: string + description: The type of field in Swimlane. + id: + type: string + description: The identifier for the field in Swimlane. + key: + type: string + description: The key for the field in Swimlane. + name: + type: string + description: The name of the field in Swimlane. + descriptionConfig: + title: Case description mapping + description: Mapping for the case description. + type: object + required: + - fieldType + - id + - key + - name + properties: + fieldType: + type: string + description: The type of field in Swimlane. + id: + type: string + description: The identifier for the field in Swimlane. + key: + type: string + description: The key for the field in Swimlane. + name: + type: string + description: The name of the field in Swimlane. + ruleNameConfig: + title: Rule name mapping + description: Mapping for the name of the alert's rule. + type: object + required: + - fieldType + - id + - key + - name + properties: + fieldType: + type: string + description: The type of field in Swimlane. + id: + type: string + description: The identifier for the field in Swimlane. + key: + type: string + description: The key for the field in Swimlane. + name: + type: string + description: The name of the field in Swimlane. + severityConfig: + title: Severity mapping + description: Mapping for the severity. + type: object + required: + - fieldType + - id + - key + - name + properties: + fieldType: + type: string + description: The type of field in Swimlane. + id: + type: string + description: The identifier for the field in Swimlane. + key: + type: string + description: The key for the field in Swimlane. + name: + type: string + description: The name of the field in Swimlane. + secrets_properties_swimlane: + title: Connector secrets properties for a Swimlane connector + description: Defines secrets for connectors when type is `.swimlane`. + type: object + properties: + apiToken: + description: Swimlane API authentication token. + type: string + create_connector_request_swimlane: + title: Create Swimlane connector request + description: The Swimlane connector uses the Swimlane REST API to create Swimlane records. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_swimlane' + connector_type_id: + type: string + description: The type of connector. + enum: + - .swimlane + example: .swimlane + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_swimlane' + secrets_properties_teams: + title: Connector secrets properties for a Microsoft Teams connector + description: Defines secrets for connectors when type is `.teams`. + type: object + additionalProperties: true + create_connector_request_teams: + title: Create Microsoft Teams connector request + description: The Microsoft Teams connector uses Incoming Webhooks. + type: object + required: + - connector_type_id + - name + - secrets + properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .teams + example: .teams + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_teams' + config_properties_tines: + title: Connector request properties for a Tines connector + description: Defines properties for connectors when type is `.tines`. + type: object + additionalProperties: true + secrets_properties_tines: + title: Connector secrets properties for a Tines connector + description: Defines secrets for connectors when type is `.tines`. + type: object + additionalProperties: true + create_connector_request_tines: + title: Create Tines connector request + description: | + The Tines connector uses Tines Webhook actions to send events via POST request. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_tines' + connector_type_id: + type: string + description: The type of connector. + enum: + - .tines + example: .tines + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_tines' + config_properties_webhook: + title: Connector request properties for a Webhook connector + description: Defines properties for connectors when type is `.webhook`. + type: object + additionalProperties: true + secrets_properties_webhook: + title: Connector secrets properties for a Webhook connector + description: Defines secrets for connectors when type is `.webhook`. + type: object + additionalProperties: true + create_connector_request_webhook: + title: Create Webhook connector request + description: | + The Webhook connector uses axios to send a POST or PUT request to a web service. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_webhook' + connector_type_id: + type: string + description: The type of connector. + enum: + - .webhook + example: .webhook + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_webhook' + config_properties_xmatters: + title: Connector request properties for a xMatters connector + description: Defines properties for connectors when type is `.xmatters`. + type: object + additionalProperties: true + secrets_properties_xmatters: + title: Connector secrets properties for an xMatters connector + description: Defines secrets for connectors when type is `.xmatters`. + type: object + additionalProperties: true + create_connector_request_xmatters: + title: Create xMatters connector request + description: | + The xMatters connector uses the xMatters Workflow for Elastic to send actionable alerts to on-call xMatters resources. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_xmatters' + connector_type_id: + type: string + description: The type of connector. + enum: + - .xmatters + example: .xmatters + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_xmatters' + is_deprecated: + type: boolean + description: Indicates whether the connector type is deprecated. + example: false + is_missing_secrets: + type: boolean + description: Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type. + example: false + is_preconfigured: + type: boolean + description: Indicates whether it is a preconfigured connector. If true, the `config` and `is_missing_secrets` properties are omitted from the response. + example: false + connector_response_properties_cases_webhook: + title: Connector request properties for a Webhook - Case Management connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_cases_webhook' + connector_type_id: + description: The type of connector. + type: string + enum: + - .cases-webhook + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_email: + title: Connector response properties for an email connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_email' + connector_type_id: + type: string + description: The type of connector. + enum: + - .email + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_index: + title: Connector response properties for an index connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_index' + connector_type_id: + type: string + description: The type of connector. + enum: + - .index + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_jira: + title: Connector response properties for a Jira connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_jira' + connector_type_id: + type: string + description: The type of connector. + enum: + - .jira + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_opsgenie: + title: Connector response properties for an Opsgenie connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_opsgenie' + connector_type_id: + type: string + description: The type of connector. + enum: + - .opsgenie + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_pagerduty: + title: Connector response properties for a PagerDuty connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_pagerduty' + connector_type_id: + type: string + description: The type of connector. + enum: + - .pagerduty + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_resilient: + title: Connector response properties for a IBM Resilient connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_resilient' + connector_type_id: + type: string + description: The type of connector. + enum: + - .resilient + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_serverlog: + title: Connector response properties for a server log connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + type: object + nullable: true + connector_type_id: + type: string + description: The type of connector. + enum: + - .server-log + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_servicenow: + title: Connector response properties for a ServiceNow ITSM connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_servicenow_itom: + title: Connector response properties for a ServiceNow ITOM connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow_itom' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-itom + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_servicenow_sir: + title: Connector response properties for a ServiceNow SecOps connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-sir + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_slack: + title: Connector response properties for a Slack connector + type: object + required: + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .slack + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_swimlane: + title: Connector response properties for a Swimlane connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_swimlane' + connector_type_id: + type: string + description: The type of connector. + enum: + - .swimlane + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_teams: + title: Connector response properties for a Microsoft Teams connector + type: object + required: + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .teams + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_tines: + title: Connector response properties for a Tines connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_tines' + connector_type_id: + type: string + description: The type of connector. + enum: + - .tines + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_webhook: + title: Connector response properties for a Webhook connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_webhook' + connector_type_id: + type: string + description: The type of connector. + enum: + - .webhook + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_xmatters: + title: Connector response properties for an xMatters connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_xmatters' + connector_type_id: + type: string + description: The type of connector. + enum: + - .xmatters + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties: + title: Connector response properties + description: The properties vary depending on the connector type. + oneOf: + - $ref: '#/components/schemas/connector_response_properties_cases_webhook' + - $ref: '#/components/schemas/connector_response_properties_email' + - $ref: '#/components/schemas/connector_response_properties_index' + - $ref: '#/components/schemas/connector_response_properties_jira' + - $ref: '#/components/schemas/connector_response_properties_opsgenie' + - $ref: '#/components/schemas/connector_response_properties_pagerduty' + - $ref: '#/components/schemas/connector_response_properties_resilient' + - $ref: '#/components/schemas/connector_response_properties_serverlog' + - $ref: '#/components/schemas/connector_response_properties_servicenow' + - $ref: '#/components/schemas/connector_response_properties_servicenow_itom' + - $ref: '#/components/schemas/connector_response_properties_servicenow_sir' + - $ref: '#/components/schemas/connector_response_properties_slack' + - $ref: '#/components/schemas/connector_response_properties_swimlane' + - $ref: '#/components/schemas/connector_response_properties_teams' + - $ref: '#/components/schemas/connector_response_properties_tines' + - $ref: '#/components/schemas/connector_response_properties_webhook' + - $ref: '#/components/schemas/connector_response_properties_xmatters' + discriminator: + propertyName: connector_type_id + update_connector_request_cases_webhook: + title: Update Webhook - Case Managment connector request + type: object + required: + - config + - name + properties: + config: + $ref: '#/components/schemas/config_properties_cases_webhook' + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_cases_webhook' + update_connector_request_index: + title: Update index connector request + type: object + required: + - config + - name + properties: + config: + $ref: '#/components/schemas/config_properties_index' + name: + type: string + description: The display name for the connector. + update_connector_request_jira: + title: Update Jira connector request + type: object + required: + - config + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_jira' + name: + type: string + description: The display name for the connector. + secrets: + $ref: '#/components/schemas/secrets_properties_jira' + update_connector_request_opsgenie: + title: Update Opsgenie connector request + type: object + required: + - config + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_opsgenie' + name: + type: string + description: The display name for the connector. + secrets: + $ref: '#/components/schemas/secrets_properties_opsgenie' + update_connector_request_resilient: + title: Update IBM Resilient connector request + type: object + required: + - config + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_resilient' + name: + type: string + description: The display name for the connector. + secrets: + $ref: '#/components/schemas/secrets_properties_resilient' + update_connector_request_serverlog: + title: Update server log connector request + type: object + required: + - name + properties: + name: + type: string + description: The display name for the connector. + update_connector_request_servicenow: + title: Update ServiceNow ITSM connector or ServiceNow SecOps request + type: object + required: + - config + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow' + name: + type: string + description: The display name for the connector. + secrets: + $ref: '#/components/schemas/secrets_properties_servicenow' + update_connector_request_servicenow_itom: + title: Create ServiceNow ITOM connector request + type: object + required: + - config + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow_itom' + name: + type: string + description: The display name for the connector. + secrets: + $ref: '#/components/schemas/secrets_properties_servicenow' + update_connector_request_swimlane: + title: Update Swimlane connector request + type: object + required: + - config + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_swimlane' + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_swimlane' connector_types: + title: Connector types type: string description: The type of connector. For example, `.email`, `.index`, `.jira`, `.opsgenie`, or `.server-log`. enum: @@ -262,18 +2101,6 @@ components: - .webhook - .xmatters example: .server-log - is_deprecated: - type: boolean - description: Indicates whether the connector type is deprecated. - example: false - is_missing_secrets: - type: boolean - description: Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type. - example: false - is_preconfigured: - type: boolean - description: Indicates whether it is a preconfigured connector. If true, the `config` and `is_missing_secrets` properties are omitted from the response. - example: false features: type: string description: | @@ -284,6 +2111,26 @@ components: - uptime - siem examples: + create_index_connector_request: + summary: Create an index connector. + value: + name: my-connector + connector_type_id: .index + config: + index: test-index + create_index_connector_response: + summary: A new index connector. + value: + id: c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad + connector_type_id: .index + name: my-connector + config: + index: test-index + refresh: false + executionTimeField: null + is_preconfigured: false + is_deprecated: false + is_missing_secrets: false get_connector_response: summary: A list of connector types value: @@ -294,6 +2141,12 @@ components: is_preconfigured: false is_deprecated: false is_missing_secrets: false + update_index_connector_request: + summary: Update an index connector. + value: + name: updated-connector + config: + index: updated-index get_connectors_response: summary: A list of connectors value: diff --git a/x-pack/plugins/actions/docs/openapi/components/examples/create_index_connector_request.yaml b/x-pack/plugins/actions/docs/openapi/components/examples/create_index_connector_request.yaml new file mode 100644 index 0000000000000..3a0a3daa043dd --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/examples/create_index_connector_request.yaml @@ -0,0 +1,6 @@ +summary: Create an index connector. +value: + name: my-connector + connector_type_id: .index + config: + index: test-index \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/examples/create_index_connector_response.yaml b/x-pack/plugins/actions/docs/openapi/components/examples/create_index_connector_response.yaml new file mode 100644 index 0000000000000..4d13a5d413598 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/examples/create_index_connector_response.yaml @@ -0,0 +1,12 @@ +summary: A new index connector. +value: + id: c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad + connector_type_id: .index + name: my-connector + config: + index: test-index + refresh: false + executionTimeField: null + is_preconfigured: false + is_deprecated: false + is_missing_secrets: false \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/examples/update_index_connector_request.yaml b/x-pack/plugins/actions/docs/openapi/components/examples/update_index_connector_request.yaml new file mode 100644 index 0000000000000..79b9463a6be51 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/examples/update_index_connector_request.yaml @@ -0,0 +1,5 @@ +summary: Update an index connector. +value: + name: updated-connector + config: + index: updated-index \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_cases_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_cases_webhook.yaml new file mode 100644 index 0000000000000..43945fbb241a2 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_cases_webhook.yaml @@ -0,0 +1,135 @@ +title: Connector request properties for Webhook - Case Management connector +required: + - createIncidentJson + - createIncidentResponseKey + - createIncidentUrl + - getIncidentResponseExternalTitleKey + - getIncidentUrl + - updateIncidentJson + - updateIncidentUrl + - viewIncidentUrl +description: Defines properties for connectors when type is `.cases-webhook`. +type: object +properties: + createCommentJson: + type: string + description: > + A JSON payload sent to the create comment URL to create a case comment. + You can use variables to add Kibana Cases data to the payload. + The required variable is `case.comment`. Due to Mustache template + variables (the text enclosed in triple braces, for example, + `{{{case.title}}}`), the JSON is not validated when you create the + connector. The JSON is validated once the Mustache variables have been + placed when the REST method runs. Manually ensure that the JSON is valid, + disregarding the Mustache variables, so the later validation will pass. + example: {"body": {{{case.comment}}}} + createCommentMethod: + type: string + description: > + The REST API HTTP request method to create a case comment in the + third-party system. Valid values are `patch`, `post`, and `put`. + default: put + enum: + - patch + - post + - put + createCommentUrl: + type: string + description: > + The REST API URL to create a case comment by ID in the third-party system. + You can use a variable to add the external system ID to the URL. If you + are using the `xpack.actions.allowedHosts setting`, add the hostname to + the allowed hosts. + example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment + createIncidentJson: + type: string + description: > + A JSON payload sent to the create case URL to create a case. You can use + variables to add case data to the payload. Required variables are + `case.title` and `case.description`. Due to Mustache template variables + (which is the text enclosed in triple braces, for example, + `{{{case.title}}}`), the JSON is not validated when you create the + connector. The JSON is validated after the Mustache variables have been + placed when REST method runs. Manually ensure that the JSON is valid to + avoid future validation errors; disregard Mustache variables during your review. + example: {"fields": {"summary": {{{case.title}}},"description": {{{case.description}}},"labels": {{{case.tags}}}}} + createIncidentMethod: + type: string + description: > + The REST API HTTP request method to create a case in the third-party + system. Valid values are `patch`, `post`, and `put`. + enum: + - patch + - post + - put + default: post + createIncidentResponseKey: + type: string + description: The JSON key in the create case response that contains the external case ID. + createIncidentUrl: + type: string + description: > + The REST API URL to create a case in the third-party system. If you are + using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. + getIncidentResponseExternalTitleKey: + type: string + description: The JSON key in get case response that contains the external case title. + getIncidentUrl: + type: string + description: > + The REST API URL to get the case by ID from the third-party system. If you + are using the `xpack.actions.allowedHosts` setting, add the hostname to + the allowed hosts. You can use a variable to add the external system ID to + the URL. Due to Mustache template variables (the text enclosed in triple + braces, for example, `{{{case.title}}}`), the JSON is not validated when + you create the connector. The JSON is validated after the Mustache + variables have been placed when REST method runs. Manually ensure that the + JSON is valid, disregarding the Mustache variables, so the later + validation will pass. + example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}} + hasAuth: + type: boolean + description: If true, a username and password for login type authentication must be provided. + default: true + headers: + type: string + description: > + A set of key-value pairs sent as headers with the request URLs for the + create case, update case, get case, and create comment methods. + updateIncidentJson: + type: string + description: > + The JSON payload sent to the update case URL to update the case. You can + use variables to add Kibana Cases data to the payload. Required variables + are `case.title` and `case.description`. Due to Mustache template + variables (which is the text enclosed in triple braces, for example, + `{{{case.title}}}`), the JSON is not validated when you create the + connector. The JSON is validated after the Mustache variables have been + placed when REST method runs. Manually ensure that the JSON is valid to + avoid future validation errors; disregard Mustache variables during your review. + example: {"fields": {"summary": {{{case.title}}},"description": {{{case.description}}},"labels": {{{case.tags}}}}} + updateIncidentMethod: + type: string + description: > + The REST API HTTP request method to update the case in the third-party + system. Valid values are `patch`, `post`, and `put`. + default: put + enum: + - patch + - post + - put + updateIncidentUrl: + type: string + description: > + The REST API URL to update the case by ID in the third-party system. You + can use a variable to add the external system ID to the URL. If you are + using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. + example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}} + viewIncidentUrl: + type: string + description: > + The URL to view the case in the external system. You can use variables to + add the external system ID or external system title to the URL. + example: https://testing-jira.atlassian.net/browse/{{{external.system.title}}} + + diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_email.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_email.yaml new file mode 100644 index 0000000000000..d87c36be08936 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_email.yaml @@ -0,0 +1,5 @@ +title: Connector request properties for an email connector +description: Defines properties for connectors when type is `.email`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_index.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_index.yaml new file mode 100644 index 0000000000000..c82f775fe15dc --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_index.yaml @@ -0,0 +1,21 @@ +title: Connector request properties for an index connector +required: + - index +description: Defines properties for connectors when type is `.index`. +type: object +properties: + executionTimeField: + description: Specifies a field that will contain the time the alert condition was detected. + default: null + type: string + nullable: true + index: + description: The Elasticsearch index to be written to. + type: string + refresh: + description: > + The refresh policy for the write request, which affects when changes are + made visible to search. Refer to the refresh setting for Elasticsearch + document APIs. + default: false + type: boolean diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_jira.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_jira.yaml new file mode 100644 index 0000000000000..1634eb83cbf59 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_jira.yaml @@ -0,0 +1,13 @@ +title: Connector request properties for a Jira connector +required: + - apiUrl + - projectKey +description: Defines properties for connectors when type is `.jira`. +type: object +properties: + apiUrl: + description: The Jira instance URL. + type: string + projectKey: + description: The Jira project key. + type: string diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_opsgenie.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_opsgenie.yaml new file mode 100644 index 0000000000000..504d536cbde3e --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_opsgenie.yaml @@ -0,0 +1,12 @@ +title: Connector request properties for an Opsgenie connector +required: + - apiUrl +description: Defines properties for connectors when type is `.opsgenie`. +type: object +properties: + apiUrl: + description: > + The Opsgenie URL. For example, `https://api.opsgenie.com` or + `https://api.eu.opsgenie.com`. If you are using the + `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. + type: string \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_pagerduty.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_pagerduty.yaml new file mode 100644 index 0000000000000..c9a98a9619d85 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_pagerduty.yaml @@ -0,0 +1,5 @@ +title: Connector request properties for a PagerDuty connector +description: Defines properties for connectors when type is `.pagerduty`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_resilient.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_resilient.yaml new file mode 100644 index 0000000000000..444be13ce4885 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_resilient.yaml @@ -0,0 +1,13 @@ +title: Connector request properties for a IBM Resilient connector +required: + - apiUrl + - orgId +description: Defines properties for connectors when type is `.resilient`. +type: object +properties: + apiUrl: + description: The IBM Resilient instance URL. + type: string + orgId: + description: The IBM Resilient organization ID. + type: string \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_servicenow.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_servicenow.yaml new file mode 100644 index 0000000000000..f7013535f2e51 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_servicenow.yaml @@ -0,0 +1,41 @@ +title: Connector request properties for a ServiceNow ITSM connector +required: + - apiUrl +description: Defines properties for connectors when type is `.servicenow`. +type: object +properties: + apiUrl: + type: string + description: The ServiceNow instance URL. + clientId: + description: > + The client ID assigned to your OAuth application. + This property is required when `isOAuth` is `true`. + type: string + isOAuth: + description: > + The type of authentication to use. The default value is false, which means + basic authentication is used instead of open authorization (OAuth). + default: false + type: string + jwtKeyId: + description: > + The key identifier assigned to the JWT verifier map of your OAuth application. + This property is required when `isOAuth` is `true`. + type: string + userIdentifierValue: + description: > + The identifier to use for OAuth authentication. This identifier should be + the user field you selected when you created an OAuth JWT API endpoint for + external clients in your ServiceNow instance. For example, if the selected + user field is `Email`, the user identifier should be the user's email + address. This property is required when `isOAuth` is `true`. + type: string + usesTableApi: + description: > + Determines whether the connector uses the Table API or the Import Set API. + This property is supported only for ServiceNow ITSM and ServiceNow SecOps + connectors. NOTE: If this property is set to `false`, the Elastic + application should be installed in ServiceNow. + default: true + type: boolean \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_servicenow_itom.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_servicenow_itom.yaml new file mode 100644 index 0000000000000..f35f96629c861 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_servicenow_itom.yaml @@ -0,0 +1,33 @@ +title: Connector request properties for a ServiceNow ITSM connector +required: + - apiUrl +description: Defines properties for connectors when type is `.servicenow`. +type: object +properties: + apiUrl: + type: string + description: The ServiceNow instance URL. + clientId: + description: > + The client ID assigned to your OAuth application. + This property is required when `isOAuth` is `true`. + type: string + isOAuth: + description: > + The type of authentication to use. The default value is false, which means + basic authentication is used instead of open authorization (OAuth). + default: false + type: string + jwtKeyId: + description: > + The key identifier assigned to the JWT verifier map of your OAuth application. + This property is required when `isOAuth` is `true`. + type: string + userIdentifierValue: + description: > + The identifier to use for OAuth authentication. This identifier should be + the user field you selected when you created an OAuth JWT API endpoint for + external clients in your ServiceNow instance. For example, if the selected + user field is `Email`, the user identifier should be the user's email + address. This property is required when `isOAuth` is `true`. + type: string \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_swimlane.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_swimlane.yaml new file mode 100644 index 0000000000000..905112276acbe --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_swimlane.yaml @@ -0,0 +1,103 @@ +title: Connector request properties for a Swimlane connector +required: + - apiUrl + - appId + - connectorType +description: Defines properties for connectors when type is `.swimlane`. +type: object +properties: + apiUrl: + description: The Swimlane instance URL. + type: string + appId: + description: The Swimlane application ID. + type: string + connectorType: + description: The type of connector. Valid values are `all`, `alerts`, and `cases`. + type: string + enum: + - all + - alerts + - cases + mappings: + title: Connector mappings properties for a Swimlane connector + description: The field mapping. + type: object + properties: + alertIdConfig: + title: Alert identifier mapping + description: Mapping for the alert ID. + type: object + required: + - fieldType + - id + - key + - name + properties: + $ref: 'mapping_properties_swimlane.yaml' + caseIdConfig: + title: Case identifier mapping + description: Mapping for the case ID. + type: object + required: + - fieldType + - id + - key + - name + properties: + $ref: 'mapping_properties_swimlane.yaml' + caseNameConfig: + title: Case name mapping + description: Mapping for the case name. + type: object + required: + - fieldType + - id + - key + - name + properties: + $ref: 'mapping_properties_swimlane.yaml' + commentsConfig: + title: Case comment mapping + description: Mapping for the case comments. + type: object + required: + - fieldType + - id + - key + - name + properties: + $ref: 'mapping_properties_swimlane.yaml' + descriptionConfig: + title: Case description mapping + description: Mapping for the case description. + type: object + required: + - fieldType + - id + - key + - name + properties: + $ref: 'mapping_properties_swimlane.yaml' + ruleNameConfig: + title: Rule name mapping + description: Mapping for the name of the alert's rule. + type: object + required: + - fieldType + - id + - key + - name + properties: + $ref: 'mapping_properties_swimlane.yaml' + severityConfig: + title: Severity mapping + description: Mapping for the severity. + type: object + required: + - fieldType + - id + - key + - name + properties: + $ref: 'mapping_properties_swimlane.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_tines.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_tines.yaml new file mode 100644 index 0000000000000..336a312d9ac8e --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_tines.yaml @@ -0,0 +1,5 @@ +title: Connector request properties for a Tines connector +description: Defines properties for connectors when type is `.tines`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_webhook.yaml new file mode 100644 index 0000000000000..6fffd356527af --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_webhook.yaml @@ -0,0 +1,5 @@ +title: Connector request properties for a Webhook connector +description: Defines properties for connectors when type is `.webhook`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_xmatters.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_xmatters.yaml new file mode 100644 index 0000000000000..6625eb09b4d35 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_xmatters.yaml @@ -0,0 +1,5 @@ +title: Connector request properties for a xMatters connector +description: Defines properties for connectors when type is `.xmatters`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties.yaml new file mode 100644 index 0000000000000..b73584568df6b --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties.yaml @@ -0,0 +1,22 @@ +title: Connector response properties +description: The properties vary depending on the connector type. +oneOf: + - $ref: 'connector_response_properties_cases_webhook.yaml' + - $ref: 'connector_response_properties_email.yaml' + - $ref: 'connector_response_properties_index.yaml' + - $ref: 'connector_response_properties_jira.yaml' + - $ref: 'connector_response_properties_opsgenie.yaml' + - $ref: 'connector_response_properties_pagerduty.yaml' + - $ref: 'connector_response_properties_resilient.yaml' + - $ref: 'connector_response_properties_serverlog.yaml' + - $ref: 'connector_response_properties_servicenow.yaml' + - $ref: 'connector_response_properties_servicenow_itom.yaml' + - $ref: 'connector_response_properties_servicenow_sir.yaml' + - $ref: 'connector_response_properties_slack.yaml' + - $ref: 'connector_response_properties_swimlane.yaml' + - $ref: 'connector_response_properties_teams.yaml' + - $ref: 'connector_response_properties_tines.yaml' + - $ref: 'connector_response_properties_webhook.yaml' + - $ref: 'connector_response_properties_xmatters.yaml' +discriminator: + propertyName: connector_type_id diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_cases_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_cases_webhook.yaml new file mode 100644 index 0000000000000..88611b62b2c99 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_cases_webhook.yaml @@ -0,0 +1,29 @@ +title: Connector request properties for a Webhook - Case Management connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_cases_webhook.yaml' + connector_type_id: + description: The type of connector. + type: string + enum: + - .cases-webhook + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_email.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_email.yaml new file mode 100644 index 0000000000000..62dac0309889e --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_email.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for an email connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_email.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .email + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_index.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_index.yaml new file mode 100644 index 0000000000000..d78d609a09b9d --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_index.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for an index connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_index.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .index + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_jira.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_jira.yaml new file mode 100644 index 0000000000000..5ff5807e200a8 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_jira.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a Jira connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_jira.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .jira + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_opsgenie.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_opsgenie.yaml new file mode 100644 index 0000000000000..850454db1a3ad --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_opsgenie.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for an Opsgenie connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_opsgenie.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .opsgenie + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_pagerduty.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_pagerduty.yaml new file mode 100644 index 0000000000000..137108efd3e14 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_pagerduty.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a PagerDuty connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_pagerduty.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .pagerduty + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_resilient.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_resilient.yaml new file mode 100644 index 0000000000000..9250c4157c660 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_resilient.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a IBM Resilient connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_resilient.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .resilient + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_serverlog.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_serverlog.yaml new file mode 100644 index 0000000000000..999a8f375d117 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_serverlog.yaml @@ -0,0 +1,30 @@ +title: Connector response properties for a server log connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + type: object + nullable: true + connector_type_id: + type: string + description: The type of connector. + enum: + - .server-log + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow.yaml new file mode 100644 index 0000000000000..a5f9d1afa0077 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a ServiceNow ITSM connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_servicenow.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow_itom.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow_itom.yaml new file mode 100644 index 0000000000000..812d367cfb17c --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow_itom.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a ServiceNow ITOM connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_servicenow_itom.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-itom + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow_sir.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow_sir.yaml new file mode 100644 index 0000000000000..ff99f5682f129 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow_sir.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a ServiceNow SecOps connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_servicenow.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-sir + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_slack.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_slack.yaml new file mode 100644 index 0000000000000..d0254e0518316 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_slack.yaml @@ -0,0 +1,26 @@ +title: Connector response properties for a Slack connector +type: object +required: + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .slack + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_swimlane.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_swimlane.yaml new file mode 100644 index 0000000000000..421abcf666038 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_swimlane.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a Swimlane connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_swimlane.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .swimlane + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_teams.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_teams.yaml new file mode 100644 index 0000000000000..bafc86f2b2977 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_teams.yaml @@ -0,0 +1,26 @@ +title: Connector response properties for a Microsoft Teams connector +type: object +required: + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .teams + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_tines.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_tines.yaml new file mode 100644 index 0000000000000..f89f85a30cd4f --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_tines.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a Tines connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_tines.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .tines + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_webhook.yaml new file mode 100644 index 0000000000000..011c39abd7ae0 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_webhook.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a Webhook connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_webhook.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .webhook + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_xmatters.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_xmatters.yaml new file mode 100644 index 0000000000000..6476adb1ab937 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_xmatters.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for an xMatters connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_xmatters.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .xmatters + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_types.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_types.yaml index 1923096b858c7..fed928120b395 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_types.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_types.yaml @@ -1,3 +1,4 @@ +title: Connector types type: string description: The type of connector. For example, `.email`, `.index`, `.jira`, `.opsgenie`, or `.server-log`. enum: diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_cases_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_cases_webhook.yaml new file mode 100644 index 0000000000000..bcbe840c03513 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_cases_webhook.yaml @@ -0,0 +1,24 @@ +title: Create Webhook - Case Managment connector request +description: > + The Webhook - Case Management connector uses axios to send POST, PUT, and GET + requests to a case management RESTful API web service. +type: object +required: + - config + - connector_type_id + - name +properties: + config: + $ref: 'config_properties_cases_webhook.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .cases-webhook + example: .cases-webhook + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_cases_webhook.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_email.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_email.yaml new file mode 100644 index 0000000000000..89f0b79c4e74b --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_email.yaml @@ -0,0 +1,27 @@ +title: Create email connector request +description: > + The email connector uses the SMTP protocol to send mail messages, using an + integration of Nodemailer. An exception is Microsoft Exchange, which uses + HTTP protocol for sending emails, Send mail. Email message text is sent as + both plain text and html text. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_email.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .email + example: .email + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_email.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_index.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_index.yaml new file mode 100644 index 0000000000000..26d6e118c1fe8 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_index.yaml @@ -0,0 +1,20 @@ +title: Create index connector request +description: The index connector indexes a document into Elasticsearch. +type: object +required: + - config + - connector_type_id + - name +properties: + config: + $ref: 'config_properties_index.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .index + example: .index + name: + type: string + description: The display name for the connector. + example: my-connector \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_jira.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_jira.yaml new file mode 100644 index 0000000000000..5b6077e875b24 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_jira.yaml @@ -0,0 +1,23 @@ +title: Create Jira connector request +description: The Jira connector uses the REST API v2 to create Jira issues. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_jira.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .jira + example: .jira + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_jira.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_opsgenie.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_opsgenie.yaml new file mode 100644 index 0000000000000..6de1296dac43c --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_opsgenie.yaml @@ -0,0 +1,23 @@ +title: Create Opsgenie connector request +description: The Opsgenie connector uses the Opsgenie alert API. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_opsgenie.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .opsgenie + example: .opsgenie + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_opsgenie.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_pagerduty.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_pagerduty.yaml new file mode 100644 index 0000000000000..498488299afd3 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_pagerduty.yaml @@ -0,0 +1,25 @@ +title: Create PagerDuty connector request +description: > + The PagerDuty connector uses the v2 Events API to trigger, acknowledge, and + resolve PagerDuty alerts. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_pagerduty.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .pagerduty + example: .pagerduty + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_pagerduty.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_resilient.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_resilient.yaml new file mode 100644 index 0000000000000..c3f766625b7da --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_resilient.yaml @@ -0,0 +1,23 @@ +title: Create IBM Resilient connector request +description: The IBM Resilient connector uses the RESILIENT REST v2 to create IBM Resilient incidents. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_resilient.yaml' + connector_type_id: + description: The type of connector. + type: string + example: .resilient + enum: + - .resilient + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_resilient.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_serverlog.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_serverlog.yaml new file mode 100644 index 0000000000000..eac0a0d65b69f --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_serverlog.yaml @@ -0,0 +1,17 @@ +title: Create server log connector request +description: This connector writes an entry to the Kibana server log. +type: object +required: + - connector_type_id + - name +properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .server-log + example: .server-log + name: + type: string + description: The display name for the connector. + example: my-connector \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow.yaml new file mode 100644 index 0000000000000..e03303dcada4f --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow.yaml @@ -0,0 +1,25 @@ +title: Create ServiceNow ITSM connector request +description: > + The ServiceNow ITSM connector uses the import set API to create ServiceNow incidents. + You can use the connector for rule actions and cases. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_servicenow.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow + example: .servicenow + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_servicenow.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_itom.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_itom.yaml new file mode 100644 index 0000000000000..70a4c05c96522 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_itom.yaml @@ -0,0 +1,25 @@ +title: Create ServiceNow ITOM connector request +description: > + The ServiceNow ITOM connector uses the event API to create ServiceNow events. + You can use the connector for rule actions. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_servicenow_itom.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-itom + example: .servicenow-itom + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_servicenow.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_sir.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_sir.yaml new file mode 100644 index 0000000000000..4d247c456f3e6 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_sir.yaml @@ -0,0 +1,25 @@ +title: Create ServiceNow SecOps connector request +description: > + The ServiceNow SecOps connector uses the import set API to create ServiceNow security incidents. + You can use the connector for rule actions and cases. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_servicenow.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-sir + example: .servicenow-sir + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_servicenow.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_slack.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_slack.yaml new file mode 100644 index 0000000000000..0634d48b543a1 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_slack.yaml @@ -0,0 +1,20 @@ +title: Create Slack connector request +description: The Slack connector uses Slack Incoming Webhooks. +type: object +required: + - connector_type_id + - name + - secrets +properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .slack + example: .slack + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_slack.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_swimlane.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_swimlane.yaml new file mode 100644 index 0000000000000..3de4f5ecbccef --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_swimlane.yaml @@ -0,0 +1,23 @@ +title: Create Swimlane connector request +description: The Swimlane connector uses the Swimlane REST API to create Swimlane records. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_swimlane.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .swimlane + example: .swimlane + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_swimlane.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_teams.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_teams.yaml new file mode 100644 index 0000000000000..5e0d449bf5546 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_teams.yaml @@ -0,0 +1,20 @@ +title: Create Microsoft Teams connector request +description: The Microsoft Teams connector uses Incoming Webhooks. +type: object +required: + - connector_type_id + - name + - secrets +properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .teams + example: .teams + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_teams.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_tines.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_tines.yaml new file mode 100644 index 0000000000000..224c3e03c4363 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_tines.yaml @@ -0,0 +1,24 @@ +title: Create Tines connector request +description: > + The Tines connector uses Tines Webhook actions to send events via POST request. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_tines.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .tines + example: .tines + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_tines.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_webhook.yaml new file mode 100644 index 0000000000000..e0ead115d48dc --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_webhook.yaml @@ -0,0 +1,24 @@ +title: Create Webhook connector request +description: > + The Webhook connector uses axios to send a POST or PUT request to a web service. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_webhook.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .webhook + example: .webhook + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_webhook.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_xmatters.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_xmatters.yaml new file mode 100644 index 0000000000000..13213d39561b2 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_xmatters.yaml @@ -0,0 +1,25 @@ +title: Create xMatters connector request +description: > + The xMatters connector uses the xMatters Workflow for Elastic to send + actionable alerts to on-call xMatters resources. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_xmatters.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .xmatters + example: .xmatters + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_xmatters.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/mapping_properties_swimlane.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/mapping_properties_swimlane.yaml new file mode 100644 index 0000000000000..9adacdd102d58 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/mapping_properties_swimlane.yaml @@ -0,0 +1,13 @@ +fieldType: + type: string + description: The type of field in Swimlane. +id: + type: string + description: The identifier for the field in Swimlane. +key: + type: string + description: The key for the field in Swimlane. +name: + type: string + description: The name of the field in Swimlane. + \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_cases_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_cases_webhook.yaml new file mode 100644 index 0000000000000..571a88975a0e8 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_cases_webhook.yaml @@ -0,0 +1,9 @@ +title: Connector secrets properties for Webhook - Case Management connector +type: object +properties: + password: + type: string + description: The password for HTTP basic authentication. If `hasAuth` is set to `true`, this property is required. + user: + type: string + description: The username for HTTP basic authentication. If `hasAuth` is set to `true`, this property is required. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_email.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_email.yaml new file mode 100644 index 0000000000000..04a3526b72ce3 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_email.yaml @@ -0,0 +1,5 @@ +title: Connector secrets properties for an email connector +description: Defines secrets for connectors when type is `.email`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_jira.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_jira.yaml new file mode 100644 index 0000000000000..dba25d0646ae8 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_jira.yaml @@ -0,0 +1,13 @@ +title: Connector secrets properties for a Jira connector +required: + - apiToken + - email +description: Defines secrets for connectors when type is `.jira`. +type: object +properties: + apiToken: + description: The Jira API authentication token for HTTP basic authentication. + type: string + email: + description: The account email for HTTP Basic authentication. + type: string diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_opsgenie.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_opsgenie.yaml new file mode 100644 index 0000000000000..fc827886e3136 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_opsgenie.yaml @@ -0,0 +1,9 @@ +title: Connector secrets properties for an Opsgenie connector +required: + - apiKey +description: Defines secrets for connectors when type is `.opsgenie`. +type: object +properties: + apiKey: + description: The Opsgenie API authentication key for HTTP Basic authentication. + type: string \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_pagerduty.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_pagerduty.yaml new file mode 100644 index 0000000000000..14d0c6fbefd69 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_pagerduty.yaml @@ -0,0 +1,5 @@ +title: Connector secrets properties for a PagerDuty connector +description: Defines secrets for connectors when type is `.pagerduty`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_resilient.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_resilient.yaml new file mode 100644 index 0000000000000..c4500a208ee94 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_resilient.yaml @@ -0,0 +1,13 @@ +title: Connector secrets properties for IBM Resilient connector +required: + - apiKeyId + - apiKeySecret +description: Defines secrets for connectors when type is `.resilient`. +type: object +properties: + apiKeyId: + type: string + description: The authentication key ID for HTTP Basic authentication. + apiKeySecret: + type: string + description: The authentication key secret for HTTP Basic authentication. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_servicenow.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_servicenow.yaml new file mode 100644 index 0000000000000..ed70fa840ecc0 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_servicenow.yaml @@ -0,0 +1,19 @@ +title: Connector secrets properties for ServiceNow ITOM, ServiceNow ITSM, and ServiceNow SecOps connectors +description: Defines secrets for connectors when type is `.servicenow`, `.servicenow-sir`, or `.servicenow-itom`. +type: object +properties: + clientSecret: + type: string + description: The client secret assigned to your OAuth application. This property is required when `isOAuth` is `true`. + password: + type: string + description: The password for HTTP basic authentication. This property is required when `isOAuth` is `false`. + privateKey: + type: string + description: The RSA private key that you created for use in ServiceNow. This property is required when `isOAuth` is `true`. + privateKeyPassword: + type: string + description: The password for the RSA private key. This property is required when `isOAuth` is `true` and you set a password on your private key. + username: + type: string + description: The username for HTTP basic authentication. This property is required when `isOAuth` is `false`. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_slack.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_slack.yaml new file mode 100644 index 0000000000000..4a681e8a195f3 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_slack.yaml @@ -0,0 +1,5 @@ +title: Connector secrets properties for a Slack connector +description: Defines secrets for connectors when type is `.slack`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_swimlane.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_swimlane.yaml new file mode 100644 index 0000000000000..e9cf5679b0c45 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_swimlane.yaml @@ -0,0 +1,7 @@ +title: Connector secrets properties for a Swimlane connector +description: Defines secrets for connectors when type is `.swimlane`. +type: object +properties: + apiToken: + description: Swimlane API authentication token. + type: string \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_teams.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_teams.yaml new file mode 100644 index 0000000000000..f5e3aa51c7528 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_teams.yaml @@ -0,0 +1,5 @@ +title: Connector secrets properties for a Microsoft Teams connector +description: Defines secrets for connectors when type is `.teams`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_tines.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_tines.yaml new file mode 100644 index 0000000000000..2373f14beae50 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_tines.yaml @@ -0,0 +1,5 @@ +title: Connector secrets properties for a Tines connector +description: Defines secrets for connectors when type is `.tines`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_webhook.yaml new file mode 100644 index 0000000000000..5a465932fb898 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_webhook.yaml @@ -0,0 +1,5 @@ +title: Connector secrets properties for a Webhook connector +description: Defines secrets for connectors when type is `.webhook`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_xmatters.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_xmatters.yaml new file mode 100644 index 0000000000000..67071884663dd --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_xmatters.yaml @@ -0,0 +1,5 @@ +title: Connector secrets properties for an xMatters connector +description: Defines secrets for connectors when type is `.xmatters`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_cases_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_cases_webhook.yaml new file mode 100644 index 0000000000000..66250b31a94eb --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_cases_webhook.yaml @@ -0,0 +1,14 @@ +title: Update Webhook - Case Managment connector request +type: object +required: + - config + - name +properties: + config: + $ref: 'config_properties_cases_webhook.yaml' + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_cases_webhook.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_email.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_email.yaml new file mode 100644 index 0000000000000..b52ba071bef53 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_email.yaml @@ -0,0 +1,13 @@ +title: Update email connector request +type: object +required: + - config + - name +properties: + config: + $ref: 'config_properties_email.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_email.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_index.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_index.yaml new file mode 100644 index 0000000000000..3fe293832a39d --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_index.yaml @@ -0,0 +1,11 @@ +title: Update index connector request +type: object +required: + - config + - name +properties: + config: + $ref: 'config_properties_index.yaml' + name: + type: string + description: The display name for the connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_jira.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_jira.yaml new file mode 100644 index 0000000000000..009442e87182f --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_jira.yaml @@ -0,0 +1,14 @@ +title: Update Jira connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_jira.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_jira.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_opsgenie.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_opsgenie.yaml new file mode 100644 index 0000000000000..ee3c511242715 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_opsgenie.yaml @@ -0,0 +1,14 @@ +title: Update Opsgenie connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_opsgenie.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_opsgenie.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_pagerduty.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_pagerduty.yaml new file mode 100644 index 0000000000000..8906c84d3d604 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_pagerduty.yaml @@ -0,0 +1,14 @@ +title: Update PagerDuty connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_pagerduty.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_pagerduty.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_resilient.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_resilient.yaml new file mode 100644 index 0000000000000..4e3957af5fa78 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_resilient.yaml @@ -0,0 +1,14 @@ +title: Update IBM Resilient connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_resilient.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_resilient.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_serverlog.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_serverlog.yaml new file mode 100644 index 0000000000000..eec0e738ca726 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_serverlog.yaml @@ -0,0 +1,8 @@ +title: Update server log connector request +type: object +required: + - name +properties: + name: + type: string + description: The display name for the connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_servicenow.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_servicenow.yaml new file mode 100644 index 0000000000000..a2fd56c21558e --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_servicenow.yaml @@ -0,0 +1,14 @@ +title: Update ServiceNow ITSM connector or ServiceNow SecOps request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_servicenow.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_servicenow.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_servicenow_itom.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_servicenow_itom.yaml new file mode 100644 index 0000000000000..81b3220bbbeb3 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_servicenow_itom.yaml @@ -0,0 +1,14 @@ +title: Create ServiceNow ITOM connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_servicenow_itom.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_servicenow.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_slack.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_slack.yaml new file mode 100644 index 0000000000000..6e1bf95b3944a --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_slack.yaml @@ -0,0 +1,11 @@ +title: Update Slack connector request +type: object +required: + - name + - secrets +properties: + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_slack.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_swimlane.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_swimlane.yaml new file mode 100644 index 0000000000000..81321351b74ec --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_swimlane.yaml @@ -0,0 +1,15 @@ +title: Update Swimlane connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_swimlane.yaml' + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_swimlane.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_teams.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_teams.yaml new file mode 100644 index 0000000000000..37a1741474ea5 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_teams.yaml @@ -0,0 +1,11 @@ +title: Update Microsoft Teams connector request +type: object +required: + - name + - secrets +properties: + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_teams.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_tines.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_tines.yaml new file mode 100644 index 0000000000000..8572f474d8bd6 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_tines.yaml @@ -0,0 +1,14 @@ +title: Update Tines connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_tines.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_tines.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_webhook.yaml new file mode 100644 index 0000000000000..6023a6795ae80 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_webhook.yaml @@ -0,0 +1,14 @@ +title: Update Webhook connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_webhook.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_webhook.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_xmatters.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_xmatters.yaml new file mode 100644 index 0000000000000..de3e962bc7543 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_xmatters.yaml @@ -0,0 +1,14 @@ +title: Update xMatters connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_xmatters.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_xmatters.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/entrypoint.yaml b/x-pack/plugins/actions/docs/openapi/entrypoint.yaml index c85da6d4d51ae..98a50c7304d58 100644 --- a/x-pack/plugins/actions/docs/openapi/entrypoint.yaml +++ b/x-pack/plugins/actions/docs/openapi/entrypoint.yaml @@ -15,8 +15,8 @@ servers: - url: 'http://localhost:5601' description: local paths: -# '/s/{spaceId}/api/actions/connector': -# $ref: 'paths/s@{spaceid}@api@actions@connector.yaml' + '/s/{spaceId}/api/actions/connector': + $ref: 'paths/s@{spaceid}@api@actions@connector.yaml' '/s/{spaceId}/api/actions/connector/{connectorId}': $ref: 'paths/s@{spaceid}@api@actions@connector@{connectorid}.yaml' '/s/{spaceId}/api/actions/connectors': diff --git a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector.yaml b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector.yaml new file mode 100644 index 0000000000000..110f35c650e91 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector.yaml @@ -0,0 +1,69 @@ +post: + summary: Creates a connector. + operationId: createConnector + description: > + You must have `all` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges. + tags: + - connectors + parameters: + - $ref: ../components/headers/kbn_xsrf.yaml + - $ref: '../components/parameters/space_id.yaml' + requestBody: + required: true + content: + application/json: + schema: + title: Create connector request body properties + description: The properties vary depending on the connector type. + oneOf: + - $ref: '../components/schemas/create_connector_request_cases_webhook.yaml' + - $ref: '../components/schemas/create_connector_request_email.yaml' + - $ref: '../components/schemas/create_connector_request_index.yaml' + - $ref: '../components/schemas/create_connector_request_jira.yaml' + - $ref: '../components/schemas/create_connector_request_opsgenie.yaml' + - $ref: '../components/schemas/create_connector_request_pagerduty.yaml' + - $ref: '../components/schemas/create_connector_request_resilient.yaml' + - $ref: '../components/schemas/create_connector_request_serverlog.yaml' + - $ref: '../components/schemas/create_connector_request_servicenow.yaml' + - $ref: '../components/schemas/create_connector_request_servicenow_itom.yaml' + - $ref: '../components/schemas/create_connector_request_servicenow_sir.yaml' + - $ref: '../components/schemas/create_connector_request_slack.yaml' + - $ref: '../components/schemas/create_connector_request_swimlane.yaml' + - $ref: '../components/schemas/create_connector_request_teams.yaml' + - $ref: '../components/schemas/create_connector_request_tines.yaml' + - $ref: '../components/schemas/create_connector_request_webhook.yaml' + - $ref: '../components/schemas/create_connector_request_xmatters.yaml' + discriminator: + propertyName: connector_type_id + examples: + createIndexConnectorRequest: + $ref: '../components/examples/create_index_connector_request.yaml' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + $ref: '../components/schemas/connector_response_properties.yaml' + examples: + createIndexConnectorResponse: + $ref: '../components/examples/create_index_connector_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + servers: + - url: https://localhost:5601 +servers: + - url: https://localhost:5601 diff --git a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector@{connectorid}.yaml b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector@{connectorid}.yaml index 53df4bcdf78ce..c1cb7df5aa0f1 100644 --- a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector@{connectorid}.yaml +++ b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector@{connectorid}.yaml @@ -11,41 +11,44 @@ get: responses: '200': description: Indicates a successful call. + content: + application/json: + schema: + $ref: '../components/schemas/connector_response_properties.yaml' + examples: + getConnectorResponse: + $ref: '../components/examples/get_connector_response.yaml' + '401': + description: Authorization information is missing or invalid. content: application/json: schema: type: object - required: - - connector_type_id - - id - - is_deprecated - - is_preconfigured - - name properties: - config: - type: object - description: The configuration for the connector. Configuration properties vary depending on the connector type. - additionalProperties: true - nullable: true - connector_type_id: - $ref: '../components/schemas/connector_types.yaml' - id: + error: type: string - description: The identifier for the connector. - example: b0766e10-d190-11ec-b04c-776c77d14fca - is_deprecated: - $ref: '../components/schemas/is_deprecated.yaml' - is_missing_secrets: - $ref: '../components/schemas/is_missing_secrets.yaml' - is_preconfigured: - $ref: '../components/schemas/is_preconfigured.yaml' - name: + example: Unauthorized + message: type: string - description: The display name for the connector. - example: my-connector - examples: - getConnectorResponse: - $ref: '../components/examples/get_connector_response.yaml' + statusCode: + type: integer + example: 401 + '404': + description: Object is not found. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Not Found + message: + type: string + example: "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + statusCode: + type: integer + example: 404 servers: - url: https://localhost:5601 @@ -64,6 +67,132 @@ delete: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + '404': + description: Object is not found. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Not Found + message: + type: string + example: "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + statusCode: + type: integer + example: 404 + servers: + - url: https://localhost:5601 + +put: + summary: Updates the attributes for a connector. + operationId: updateConnector + description: > + You must have `all` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges. + tags: + - connectors + parameters: + - $ref: ../components/headers/kbn_xsrf.yaml + - $ref: '../components/parameters/connector_id.yaml' + - $ref: '../components/parameters/space_id.yaml' + requestBody: + required: true + content: + application/json: + schema: + title: Update connector request body properties + description: The properties vary depending on the connector type. + oneOf: + - $ref: '../components/schemas/update_connector_request_cases_webhook.yaml' +# - $ref: '../components/schemas/update_connector_request_email.yaml' + - $ref: '../components/schemas/update_connector_request_index.yaml' + - $ref: '../components/schemas/update_connector_request_jira.yaml' + - $ref: '../components/schemas/update_connector_request_opsgenie.yaml' +# - $ref: '../components/schemas/update_connector_request_pagerduty.yaml' + - $ref: '../components/schemas/update_connector_request_resilient.yaml' + - $ref: '../components/schemas/update_connector_request_serverlog.yaml' + - $ref: '../components/schemas/update_connector_request_servicenow.yaml' + - $ref: '../components/schemas/update_connector_request_servicenow_itom.yaml' +# - $ref: '../components/schemas/update_connector_request_slack.yaml' + - $ref: '../components/schemas/update_connector_request_swimlane.yaml' +# - $ref: '../components/schemas/update_connector_request_teams.yaml' +# - $ref: '../components/schemas/update_connector_request_tines.yaml' +# - $ref: '../components/schemas/update_connector_request_webhook.yaml' +# - $ref: '../components/schemas/update_connector_request_xmatters.yaml' + examples: + updateIndexConnectorRequest: + $ref: '../components/examples/update_index_connector_request.yaml' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + $ref: '../components/schemas/connector_response_properties.yaml' + '400': + description: Indicates a bad request. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Bad Request + message: + type: string + example: "error validating action type config: [index]: expected value of type [string] but got [undefined]" + statusCode: + type: integer + example: 400 + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + '404': + description: Object is not found. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Not Found + message: + type: string + example: "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + statusCode: + type: integer + example: 404 servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector_types.yaml b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector_types.yaml index 5dcd403aea99c..001da54c13c14 100644 --- a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector_types.yaml +++ b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector_types.yaml @@ -18,6 +18,8 @@ get: content: application/json: schema: + title: Get connector types response body properties + description: The properties vary for each connector type. type: array items: type: object @@ -56,6 +58,21 @@ get: examples: getConnectorTypesResponse: $ref: '../components/examples/get_connector_types_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connectors.yaml b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connectors.yaml index 36bd852c12f6f..2a0a075703f8a 100644 --- a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connectors.yaml +++ b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connectors.yaml @@ -15,6 +15,8 @@ get: schema: type: array items: + title: Get connectors response body properties + description: The properties vary for each connector type. type: object required: - connector_type_id @@ -53,6 +55,21 @@ get: examples: getConnectorsResponse: $ref: '../components/examples/get_connectors_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 servers: - url: https://localhost:5601 servers: From fa68cb432b306ca54a68eceb5ca86f0dff326281 Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Tue, 17 Jan 2023 09:53:48 -0800 Subject: [PATCH 08/44] [DOCS] Create OAS for get rule types and get alerting framework health (#148774) --- .../rules/rule-apis-passthru.asciidoc | 512 ++++++++++- docs/api/alerting/health.asciidoc | 6 + docs/api/alerting/list_rule_types.asciidoc | 7 + .../alerting/docs/openapi/bundled.json | 849 +++++++++++++++++- .../alerting/docs/openapi/bundled.yaml | 560 +++++++++++- .../examples/get_health_response.yaml | 25 + .../examples/get_rule_types_response.yaml | 81 ++ .../components/schemas/401_response.yaml | 15 + .../components/schemas/404_response.yaml | 15 + .../alerting/docs/openapi/entrypoint.yaml | 8 +- .../s@{spaceid}@api@alerting@_health.yaml | 126 +++ ...@{spaceid}@api@alerting@rule@{ruleid}.yaml | 42 +- ...}@api@alerting@rule@{ruleid}@_disable.yaml | 14 +- ...d}@api@alerting@rule@{ruleid}@_enable.yaml | 14 +- ...@api@alerting@rule@{ruleid}@_mute_all.yaml | 8 +- ...pi@alerting@rule@{ruleid}@_unmute_all.yaml | 8 +- ...g@rule@{ruleid}@alert@{alertid}@_mute.yaml | 8 +- ...rule@{ruleid}@alert@{alertid}@_unmute.yaml | 8 +- .../s@{spaceid}@api@alerting@rule_types.yaml | 198 ++++ .../s@{spaceid}@api@alerting@rules@_find.yaml | 6 + 20 files changed, 2474 insertions(+), 36 deletions(-) create mode 100644 x-pack/plugins/alerting/docs/openapi/components/examples/get_health_response.yaml create mode 100644 x-pack/plugins/alerting/docs/openapi/components/examples/get_rule_types_response.yaml create mode 100644 x-pack/plugins/alerting/docs/openapi/components/schemas/401_response.yaml create mode 100644 x-pack/plugins/alerting/docs/openapi/components/schemas/404_response.yaml create mode 100644 x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@_health.yaml create mode 100644 x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule_types.yaml diff --git a/docs/api-generated/rules/rule-apis-passthru.asciidoc b/docs/api-generated/rules/rule-apis-passthru.asciidoc index 0e9260905cbc8..8ef9fdfacf560 100644 --- a/docs/api-generated/rules/rule-apis-passthru.asciidoc +++ b/docs/api-generated/rules/rule-apis-passthru.asciidoc @@ -22,7 +22,9 @@ Any modifications made to this file will be overwritten.
  • post /s/{spaceId}/api/alerting/rule/{ruleId}/_disable
  • post /s/{spaceId}/api/alerting/rule/{ruleId}/_enable
  • get /s/{spaceId}/api/alerting/rules/_find
  • +
  • get /s/{spaceId}/api/alerting/_health
  • get /s/{spaceId}/api/alerting/rule/{ruleId}
  • +
  • get /s/{spaceId}/api/alerting/rule_types
  • post /s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_mute
  • post /s/{spaceId}/api/alerting/rule/{ruleId}/_mute_all
  • post /s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_unmute
  • @@ -63,18 +65,30 @@ Any modifications made to this file will be overwritten. +

    Produces

    + This API call produces the following media types according to the Accept request header; + the media type will be conveyed by the Content-Type response header. +
      +
    • application/json
    • +

    Responses

    204

    Indicates a successful call. +

    401

    + Authorization information is missing or invalid. + 401_response +

    404

    + Object is not found. + 404_response
    Up
    post /s/{spaceId}/api/alerting/rule/{ruleId}/_disable
    -
    Disable a rule. (disableRule)
    +
    Disables a rule. (disableRule)
    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.

    Path parameters

    @@ -102,18 +116,30 @@ Any modifications made to this file will be overwritten. +

    Produces

    + This API call produces the following media types according to the Accept request header; + the media type will be conveyed by the Content-Type response header. +
      +
    • application/json
    • +

    Responses

    204

    Indicates a successful call. +

    401

    + Authorization information is missing or invalid. + 401_response +

    404

    + Object is not found. + 404_response

    Up
    post /s/{spaceId}/api/alerting/rule/{ruleId}/_enable
    -
    Enable a rule. (enableRule)
    +
    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.

    Path parameters

    @@ -141,11 +167,23 @@ Any modifications made to this file will be overwritten. +

    Produces

    + This API call produces the following media types according to the Accept request header; + the media type will be conveyed by the Content-Type response header. +
      +
    • application/json
    • +

    Responses

    204

    Indicates a successful call. +

    401

    + Authorization information is missing or invalid. + 401_response +

    404

    + Object is not found. + 401_response

    +
    +
    +
    + Up +
    get /s/{spaceId}/api/alerting/_health
    +
    Retrieves the health status of the alerting framework. (getAlertingHealth)
    +
    You must have read privileges for the Management > Stack Rules feature or for at least one of the Analytics > Discover, Analytics > Machine Learning, Observability, or Security features.
    + +

    Path parameters

    +
    +
    spaceId (required)
    + +
    Path Parameter — An identifier for the space. If /s/ and the identifier are omitted from the path, the default space is used. default: null
    +
    + + + + + + +

    Return type

    + + + + +

    Example data

    +
    Content-Type: application/json
    +
    {
    +  "alerting_framework_health" : {
    +    "execution_health" : {
    +      "status" : "ok",
    +      "timestamp" : "2023-01-13T01:28:00.28Z"
    +    },
    +    "read_health" : {
    +      "status" : "ok",
    +      "timestamp" : "2023-01-13T01:28:00.28Z"
    +    },
    +    "decryption_health" : {
    +      "status" : "ok",
    +      "timestamp" : "2023-01-13T01:28:00.28Z"
    +    }
    +  },
    +  "alerting_framework_heath" : {
    +    "_deprecated" : "This state property has a typo, use \"alerting_framework_health\" instead.",
    +    "execution_health" : {
    +      "status" : "ok",
    +      "timestamp" : "2023-01-13T01:28:00.28Z"
    +    },
    +    "read_health" : {
    +      "status" : "ok",
    +      "timestamp" : "2023-01-13T01:28:00.28Z"
    +    },
    +    "decryption_health" : {
    +      "status" : "ok",
    +      "timestamp" : "2023-01-13T01:28:00.28Z"
    +    }
    +  },
    +  "has_permanent_encryption_key" : true,
    +  "is_sufficiently_secure" : true
    +}
    + +

    Produces

    + This API call produces the following media types according to the Accept request header; + the media type will be conveyed by the Content-Type response header. +
      +
    • application/json
    • +
    + +

    Responses

    +

    200

    + Indicates a successful call. + getAlertingHealth_200_response +

    401

    + Authorization information is missing or invalid. + 401_response

    Up
    get /s/{spaceId}/api/alerting/rule/{ruleId}
    -
    Retrieve a rule by its identifier. (getRule)
    +
    Retrieves a rule by its identifier. (getRule)
    You must have read privileges for the appropriate Kibana features, depending on the consumer and rule_type_id of the rules you're seeking. For example, the Management > Stack Rules feature, Analytics > Discover and Machine Learning features, Observability features, or Security features. To get rules associated with the Stack Monitoring feature, use the monitoring_user built-in role.

    Path parameters

    @@ -424,13 +544,154 @@ Any modifications made to this file will be overwritten.

    200

    Indicates a successful call. rule_response_properties +

    401

    + Authorization information is missing or invalid. + 401_response +

    404

    + Object is not found. + 404_response +
    +
    +
    +
    + Up +
    get /s/{spaceId}/api/alerting/rule_types
    +
    Retrieves a list of rule types. (getRuleTypes)
    +
    If you have read privileges for one or more Kibana features, the API response contains information about the appropriate rule types. For example, there are rule types associated with the Management > Stack Rules feature, Analytics > Discover and Machine Learning features, Observability features, and Security features. To get rule types associated with the Stack Monitoring feature, use the monitoring_user built-in role.
    + +

    Path parameters

    +
    +
    spaceId (required)
    + +
    Path Parameter — An identifier for the space. If /s/ and the identifier are omitted from the path, the default space is used. default: null
    +
    + + + + + + +

    Return type

    + + + + +

    Example data

    +
    Content-Type: application/json
    +
    {
    +  "recovery_action_group" : {
    +    "name" : "name",
    +    "id" : "id"
    +  },
    +  "does_set_recovery_context" : true,
    +  "is_exportable" : true,
    +  "authorized_consumers" : {
    +    "alerts" : {
    +      "all" : true,
    +      "read" : true
    +    },
    +    "discover" : {
    +      "all" : true,
    +      "read" : true
    +    },
    +    "stackAlerts" : {
    +      "all" : true,
    +      "read" : true
    +    },
    +    "infrastructure" : {
    +      "all" : true,
    +      "read" : true
    +    },
    +    "siem" : {
    +      "all" : true,
    +      "read" : true
    +    },
    +    "monitoring" : {
    +      "all" : true,
    +      "read" : true
    +    },
    +    "logs" : {
    +      "all" : true,
    +      "read" : true
    +    },
    +    "apm" : {
    +      "all" : true,
    +      "read" : true
    +    },
    +    "ml" : {
    +      "all" : true,
    +      "read" : true
    +    },
    +    "uptime" : {
    +      "all" : true,
    +      "read" : true
    +    }
    +  },
    +  "action_groups" : [ {
    +    "name" : "name",
    +    "id" : "id"
    +  }, {
    +    "name" : "name",
    +    "id" : "id"
    +  } ],
    +  "minimum_license_required" : "basic",
    +  "action_variables" : {
    +    "context" : [ {
    +      "name" : "name",
    +      "description" : "description",
    +      "useWithTripleBracesInTemplates" : true
    +    }, {
    +      "name" : "name",
    +      "description" : "description",
    +      "useWithTripleBracesInTemplates" : true
    +    } ],
    +    "state" : [ {
    +      "name" : "name",
    +      "description" : "description"
    +    }, {
    +      "name" : "name",
    +      "description" : "description"
    +    } ],
    +    "params" : [ {
    +      "name" : "name",
    +      "description" : "description"
    +    }, {
    +      "name" : "name",
    +      "description" : "description"
    +    } ]
    +  },
    +  "rule_task_timeout" : "5m",
    +  "name" : "name",
    +  "enabled_in_license" : true,
    +  "producer" : "stackAlerts",
    +  "id" : "id",
    +  "default_action_group_id" : "default_action_group_id"
    +}
    + +

    Produces

    + This API call produces the following media types according to the Accept request header; + the media type will be conveyed by the Content-Type response header. +
      +
    • application/json
    • +
    + +

    Responses

    +

    200

    + Indicates a successful call. + +

    401

    + Authorization information is missing or invalid. + 401_response

    Up
    post /s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_mute
    -
    Mute an alert. (muteAlert)
    +
    Mutes an alert. (muteAlert)
    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. If the rule has actions, you must also have read privileges for the Management > Actions and Connectors feature.

    Path parameters

    @@ -460,18 +721,27 @@ Any modifications made to this file will be overwritten. +

    Produces

    + This API call produces the following media types according to the Accept request header; + the media type will be conveyed by the Content-Type response header. +
      +
    • application/json
    • +

    Responses

    204

    Indicates a successful call. +

    401

    + Authorization information is missing or invalid. + 401_response

    Up
    post /s/{spaceId}/api/alerting/rule/{ruleId}/_mute_all
    -
    Mute all alerts. (muteAllAlerts)
    +
    Mutes all alerts. (muteAllAlerts)
    This API snoozes the notifications for the rule indefinitely. The rule checks continue to occur but alerts will not trigger any actions. 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. If the rule has actions, you must also have read privileges for the Management > Actions and Connectors feature.

    Path parameters

    @@ -499,18 +769,27 @@ Any modifications made to this file will be overwritten. +

    Produces

    + This API call produces the following media types according to the Accept request header; + the media type will be conveyed by the Content-Type response header. +
      +
    • application/json
    • +

    Responses

    204

    Indicates a successful call. +

    401

    + Authorization information is missing or invalid. + 401_response

    Up
    post /s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_unmute
    -
    Unmute an alert. (unmuteAlert)
    +
    Unmutes an alert. (unmuteAlert)
    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. If the rule has actions, you must also have read privileges for the Management > Actions and Connectors feature.

    Path parameters

    @@ -540,18 +819,27 @@ Any modifications made to this file will be overwritten. +

    Produces

    + This API call produces the following media types according to the Accept request header; + the media type will be conveyed by the Content-Type response header. +
      +
    • application/json
    • +

    Responses

    204

    Indicates a successful call. +

    401

    + Authorization information is missing or invalid. + 401_response

    Up
    post /s/{spaceId}/api/alerting/rule/{ruleId}/_unmute_all
    -
    Unmute all alerts. (unmuteAllAlerts)
    +
    Unmutes all alerts. (unmuteAllAlerts)
    If the rule has its notifications snoozed indefinitely, this API cancels the snooze. 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. If the rule has actions, you must also have read privileges for the Management > Actions and Connectors feature.

    Path parameters

    @@ -579,11 +867,20 @@ Any modifications made to this file will be overwritten. +

    Produces

    + This API call produces the following media types according to the Accept request header; + the media type will be conveyed by the Content-Type response header. +
      +
    • application/json
    • +

    Responses

    204

    Indicates a successful call. +

    401

    + Authorization information is missing or invalid. + 401_response


    @@ -710,10 +1013,27 @@ Any modifications made to this file will be overwritten.

    Table of Contents

      +
    1. 401_response - Unsuccessful rule API response
    2. +
    3. 404_response -
    4. actions_inner -
    5. findRules_200_response -
    6. findRules_has_reference_parameter -
    7. findRules_search_fields_parameter -
    8. +
    9. getAlertingHealth_200_response -
    10. +
    11. getAlertingHealth_200_response_alerting_framework_health -
    12. +
    13. getAlertingHealth_200_response_alerting_framework_health_decryption_health -
    14. +
    15. getAlertingHealth_200_response_alerting_framework_health_execution_health -
    16. +
    17. getAlertingHealth_200_response_alerting_framework_health_read_health -
    18. +
    19. getAlertingHealth_200_response_alerting_framework_heath -
    20. +
    21. getAlertingHealth_200_response_alerting_framework_heath_decryption_health -
    22. +
    23. getRuleTypes_200_response_inner -
    24. +
    25. getRuleTypes_200_response_inner_action_groups_inner -
    26. +
    27. getRuleTypes_200_response_inner_action_variables -
    28. +
    29. getRuleTypes_200_response_inner_action_variables_context_inner -
    30. +
    31. getRuleTypes_200_response_inner_action_variables_params_inner -
    32. +
    33. getRuleTypes_200_response_inner_authorized_consumers -
    34. +
    35. getRuleTypes_200_response_inner_authorized_consumers_alerts -
    36. +
    37. getRuleTypes_200_response_inner_recovery_action_group -
    38. notify_when -
    39. rule_response_properties - Rule response properties
    40. rule_response_properties_execution_status -
    41. @@ -723,6 +1043,32 @@ Any modifications made to this file will be overwritten.
    42. update_rule_request - Update rule request
    +
    +

    401_response - Unsuccessful rule API response Up

    +
    +
    +
    error (optional)
    +
    Enum:
    +
    Unauthorized
    +
    message (optional)
    +
    statusCode (optional)
    +
    Enum:
    +
    401
    +
    +
    +
    +

    404_response - Up

    +
    +
    +
    error (optional)
    +
    Enum:
    +
    Not Found
    +
    message (optional)
    +
    statusCode (optional)
    +
    Enum:
    +
    404
    +
    +

    actions_inner - Up

    @@ -756,6 +1102,158 @@ Any modifications made to this file will be overwritten.
    +
    +

    getAlertingHealth_200_response - Up

    +
    +
    +
    alerting_framework_heath (optional)
    +
    alerting_framework_health (optional)
    +
    has_permanent_encryption_key (optional)
    Boolean If false, the encrypted saved object plugin does not have a permanent encryption key.
    +
    is_sufficiently_secure (optional)
    Boolean If false, security is enabled but TLS is not.
    +
    +
    +
    +

    getAlertingHealth_200_response_alerting_framework_health - Up

    +
    Three substates identify the health of the alerting framework: decryption_health, execution_health, and read_health.
    + +
    +
    +

    getAlertingHealth_200_response_alerting_framework_health_decryption_health - Up

    +
    The timestamp and status of the rule decryption.
    +
    +
    status (optional)
    +
    Enum:
    +
    error
    ok
    warn
    +
    timestamp (optional)
    Date format: date-time
    +
    +
    +
    +

    getAlertingHealth_200_response_alerting_framework_health_execution_health - Up

    +
    The timestamp and status of the rule run.
    +
    +
    status (optional)
    +
    Enum:
    +
    error
    ok
    warn
    +
    timestamp (optional)
    Date format: date-time
    +
    +
    +
    +

    getAlertingHealth_200_response_alerting_framework_health_read_health - Up

    +
    The timestamp and status of the rule reading events.
    +
    +
    status (optional)
    +
    Enum:
    +
    error
    ok
    warn
    +
    timestamp (optional)
    Date format: date-time
    +
    +
    + +
    +

    getAlertingHealth_200_response_alerting_framework_heath_decryption_health - Up

    +
    +
    +
    status (optional)
    +
    timestamp (optional)
    Date format: date-time
    +
    +
    +
    +

    getRuleTypes_200_response_inner - Up

    +
    +
    +
    action_groups (optional)
    array[getRuleTypes_200_response_inner_action_groups_inner] An explicit list of groups for which the rule type can schedule actions, each with the action group's unique ID and human readable name. Rule actions validation uses this configuration to ensure that groups are valid.
    +
    action_variables (optional)
    +
    authorized_consumers (optional)
    +
    default_action_group_id (optional)
    String The default identifier for the rule type group.
    +
    does_set_recovery_context (optional)
    Boolean Indicates whether the rule passes context variables to its recovery action.
    +
    enabled_in_license (optional)
    Boolean Indicates whether the rule type is enabled or disabled based on the subscription.
    +
    id (optional)
    String The unique identifier for the rule type.
    +
    is_exportable (optional)
    Boolean Indicates whether the rule type is exportable in Stack Management > Saved Objects.
    +
    minimum_license_required (optional)
    String The subscriptions required to use the rule type.
    +
    name (optional)
    String The descriptive name of the rule type.
    +
    producer (optional)
    String An identifier for the application that produces this rule type.
    +
    recovery_action_group (optional)
    +
    rule_task_timeout (optional)
    +
    +
    + +
    +

    getRuleTypes_200_response_inner_action_variables - Up

    +
    A list of action variables that the rule type makes available via context and state in action parameter templates, and a short human readable description. When you create a rule in Kibana, it uses this information to prompt you for these variables in action parameter editors.
    + +
    +
    +

    getRuleTypes_200_response_inner_action_variables_context_inner - Up

    +
    +
    +
    name (optional)
    +
    description (optional)
    +
    useWithTripleBracesInTemplates (optional)
    +
    +
    +
    +

    getRuleTypes_200_response_inner_action_variables_params_inner - Up

    +
    +
    +
    description (optional)
    +
    name (optional)
    +
    +
    + + +
    +

    getRuleTypes_200_response_inner_recovery_action_group - Up

    +
    An action group to use when an alert goes from an active state to an inactive one.
    +
    +
    id (optional)
    +
    name (optional)
    +
    +

    notify_when - Up

    Indicates how often alerts generate actions. Valid values include: onActionGroupChange: Actions run when the alert status changes; onActiveAlert: Actions run when the alert becomes active and at each check interval while the rule conditions are met; onThrottleInterval: Actions run when the alert becomes active and at the interval specified in the throttle property while the rule conditions are met.
    diff --git a/docs/api/alerting/health.asciidoc b/docs/api/alerting/health.asciidoc index 1f0c8936419b5..ce22ece799b76 100644 --- a/docs/api/alerting/health.asciidoc +++ b/docs/api/alerting/health.asciidoc @@ -6,6 +6,12 @@ Retrieve the health status of the alerting framework. +[NOTE] +==== +For the most up-to-date API details, refer to the +{kib-repo}/tree/{branch}/x-pack/plugins/alerting/docs/openapi[open API specification]. For a preview, check out <>. +==== + [[get-alerting-framework-health-api-request]] === {api-request-title} diff --git a/docs/api/alerting/list_rule_types.asciidoc b/docs/api/alerting/list_rule_types.asciidoc index 1d37ff9e4dbcc..32b4be086705a 100644 --- a/docs/api/alerting/list_rule_types.asciidoc +++ b/docs/api/alerting/list_rule_types.asciidoc @@ -6,6 +6,13 @@ Retrieve a list of rule types that the user is authorized to access. +[NOTE] +==== +For the most up-to-date API details, refer to the +{kib-repo}/tree/{branch}/x-pack/plugins/alerting/docs/openapi[open API specification]. For a preview, check out <>. +==== + + [[list-rule-types-api-request]] === {api-request-title} diff --git a/x-pack/plugins/alerting/docs/openapi/bundled.json b/x-pack/plugins/alerting/docs/openapi/bundled.json index 8adf80f41a836..53b0ad2e75a73 100644 --- a/x-pack/plugins/alerting/docs/openapi/bundled.json +++ b/x-pack/plugins/alerting/docs/openapi/bundled.json @@ -27,7 +27,7 @@ "paths": { "/s/{spaceId}/api/alerting/rule/{ruleId}": { "get": { - "summary": "Retrieve a rule by its identifier.", + "summary": "Retrieves a rule by its identifier.", "operationId": "getRule", "description": "You must have `read` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rules you're seeking. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. To get rules associated with the **Stack Monitoring** feature, use the `monitoring_user` built-in role.\n", "tags": [ @@ -50,14 +50,39 @@ "$ref": "#/components/schemas/rule_response_properties" }, "examples": { - "updateRuleResponse": { + "getRuleResponse": { "$ref": "#/components/examples/get_rule_response" } } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } } - } + }, + "servers": [ + { + "url": "https://localhost:5601" + } + ] }, "delete": { "summary": "Deletes a rule.", @@ -80,6 +105,26 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } } }, "servers": [ @@ -136,6 +181,26 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } } }, "servers": [ @@ -152,7 +217,7 @@ }, "/s/{spaceId}/api/alerting/rule/{ruleId}/_disable": { "post": { - "summary": "Disable a rule.", + "summary": "Disables a rule.", "operationId": "disableRule", "description": "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", "tags": [ @@ -172,6 +237,26 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } } }, "servers": [ @@ -188,7 +273,7 @@ }, "/s/{spaceId}/api/alerting/rule/{ruleId}/_enable": { "post": { - "summary": "Enable a rule.", + "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", "tags": [ @@ -208,6 +293,26 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } } }, "servers": [ @@ -380,6 +485,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } } }, "servers": [ @@ -394,9 +509,471 @@ } ] }, + "/s/{spaceId}/api/alerting/_health": { + "get": { + "summary": "Retrieves the health status of the alerting framework.", + "operationId": "getAlertingHealth", + "description": "You must have `read` privileges for the **Management > Stack Rules** feature or for at least one of the **Analytics > Discover**, **Analytics > Machine Learning**, **Observability**, or **Security** features.\n", + "tags": [ + "alerting" + ], + "parameters": [ + { + "$ref": "#/components/parameters/space_id" + } + ], + "responses": { + "200": { + "description": "Indicates a successful call.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "alerting_framework_heath": { + "type": "object", + "description": "This property has a typo. Use `alerting_framework_health` instead.", + "deprecated": true, + "properties": { + "_deprecated": { + "type": "string", + "example": "This state property has a typo, use \"alerting_framework_health\" instead." + }, + "decryption_health": { + "type": "object", + "properties": { + "status": { + "type": "string", + "example": "ok" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "example": "2023-01-13T01:28:00.280Z" + } + } + }, + "execution_health": { + "type": "object", + "properties": { + "status": { + "type": "string", + "example": "ok" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "example": "2023-01-13T01:28:00.280Z" + } + } + }, + "read_health": { + "type": "object", + "properties": { + "status": { + "type": "string", + "example": "ok" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "example": "2023-01-13T01:28:00.280Z" + } + } + } + } + }, + "alerting_framework_health": { + "type": "object", + "description": "Three substates identify the health of the alerting framework: `decryption_health`, `execution_health`, and `read_health`.\n", + "properties": { + "decryption_health": { + "type": "object", + "description": "The timestamp and status of the rule decryption.", + "properties": { + "status": { + "type": "string", + "example": "ok", + "enum": [ + "error", + "ok", + "warn" + ] + }, + "timestamp": { + "type": "string", + "format": "date-time", + "example": "2023-01-13T01:28:00.280Z" + } + } + }, + "execution_health": { + "type": "object", + "description": "The timestamp and status of the rule run.", + "properties": { + "status": { + "type": "string", + "example": "ok", + "enum": [ + "error", + "ok", + "warn" + ] + }, + "timestamp": { + "type": "string", + "format": "date-time", + "example": "2023-01-13T01:28:00.280Z" + } + } + }, + "read_health": { + "type": "object", + "description": "The timestamp and status of the rule reading events.", + "properties": { + "status": { + "type": "string", + "example": "ok", + "enum": [ + "error", + "ok", + "warn" + ] + }, + "timestamp": { + "type": "string", + "format": "date-time", + "example": "2023-01-13T01:28:00.280Z" + } + } + } + } + }, + "has_permanent_encryption_key": { + "type": "boolean", + "description": "If `false`, the encrypted saved object plugin does not have a permanent encryption key.", + "example": true + }, + "is_sufficiently_secure": { + "type": "boolean", + "description": "If `false`, security is enabled but TLS is not.", + "example": true + } + } + }, + "examples": { + "getAlertingHealthResponse": { + "$ref": "#/components/examples/get_health_response" + } + } + } + } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + } + } + }, + "servers": [ + { + "url": "https://localhost:5601" + } + ] + }, + "/s/{spaceId}/api/alerting/rule_types": { + "get": { + "summary": "Retrieves a list of rule types.", + "operationId": "getRuleTypes", + "description": "If you have `read` privileges for one or more Kibana features, the API response contains information about the appropriate rule types. For example, there are rule types associated with the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, and **Security** features. To get rule types associated with the **Stack Monitoring** feature, use the `monitoring_user` built-in role.\n", + "tags": [ + "alerting" + ], + "parameters": [ + { + "$ref": "#/components/parameters/space_id" + } + ], + "responses": { + "200": { + "description": "Indicates a successful call.", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "action_groups": { + "description": "An explicit list of groups for which the rule type can schedule actions, each with the action group's unique ID and human readable name. Rule actions validation uses this configuration to ensure that groups are valid.\n", + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + } + }, + "action_variables": { + "description": "A list of action variables that the rule type makes available via context and state in action parameter templates, and a short human readable description. When you create a rule in Kibana, it uses this information to prompt you for these variables in action parameter editors.\n", + "type": "object", + "properties": { + "context": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "useWithTripleBracesInTemplates": { + "type": "boolean" + } + } + } + }, + "params": { + "type": "array", + "items": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + } + } + } + }, + "state": { + "type": "array", + "items": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + } + } + } + } + } + }, + "authorized_consumers": { + "description": "The list of the plugins IDs that have access to the rule type.", + "type": "object", + "properties": { + "alerts": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "apm": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "discover": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "infrastructure": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "logs": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "ml": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "monitoring": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "siem": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "stackAlerts": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "uptime": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + } + } + }, + "default_action_group_id": { + "description": "The default identifier for the rule type group.", + "type": "string" + }, + "does_set_recovery_context": { + "description": "Indicates whether the rule passes context variables to its recovery action.", + "type": "boolean" + }, + "enabled_in_license": { + "description": "Indicates whether the rule type is enabled or disabled based on the subscription.", + "type": "boolean" + }, + "id": { + "description": "The unique identifier for the rule type.", + "type": "string" + }, + "is_exportable": { + "description": "Indicates whether the rule type is exportable in **Stack Management > Saved Objects**.", + "type": "boolean" + }, + "minimum_license_required": { + "description": "The subscriptions required to use the rule type.", + "type": "string", + "example": "basic" + }, + "name": { + "description": "The descriptive name of the rule type.", + "type": "string" + }, + "producer": { + "description": "An identifier for the application that produces this rule type.", + "type": "string", + "example": "stackAlerts" + }, + "recovery_action_group": { + "description": "An action group to use when an alert goes from an active state to an inactive one.", + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "rule_task_timeout": { + "type": "string", + "example": "5m" + } + } + } + }, + "examples": { + "getRuleTypesResponse": { + "$ref": "#/components/examples/get_rule_types_response" + } + } + } + } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + } + } + }, + "servers": [ + { + "url": "https://localhost:5601" + } + ] + }, "/s/{spaceId}/api/alerting/rule/{ruleId}/_mute_all": { "post": { - "summary": "Mute all alerts.", + "summary": "Mutes all alerts.", "operationId": "muteAllAlerts", "description": "This API snoozes the notifications for the rule indefinitely. The rule checks continue to occur but alerts will not trigger any actions. 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. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature.\n", "tags": [ @@ -416,6 +993,16 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } } }, "servers": [ @@ -432,7 +1019,7 @@ }, "/s/{spaceId}/api/alerting/rule/{ruleId}/_unmute_all": { "post": { - "summary": "Unmute all alerts.", + "summary": "Unmutes all alerts.", "operationId": "unmuteAllAlerts", "description": "If the rule has its notifications snoozed indefinitely, this API cancels the snooze. 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. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature.\n", "tags": [ @@ -452,6 +1039,16 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } } }, "servers": [ @@ -468,7 +1065,7 @@ }, "/s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_mute": { "post": { - "summary": "Mute an alert.", + "summary": "Mutes an alert.", "operationId": "muteAlert", "description": "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. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. \n", "tags": [ @@ -491,6 +1088,16 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } } }, "servers": [ @@ -507,7 +1114,7 @@ }, "/s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_unmute": { "post": { - "summary": "Unmute an alert.", + "summary": "Unmutes an alert.", "operationId": "unmuteAlert", "description": "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. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. \n", "tags": [ @@ -530,6 +1137,16 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } } }, "servers": [ @@ -838,6 +1455,52 @@ } } }, + "401_response": { + "type": "object", + "title": "Unsuccessful rule API response", + "properties": { + "error": { + "type": "string", + "example": "Unauthorized", + "enum": [ + "Unauthorized" + ] + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "example": 401, + "enum": [ + 401 + ] + } + } + }, + "404_response": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Not Found", + "enum": [ + "Not Found" + ] + }, + "message": { + "type": "string", + "example": "Saved object [alert/caaad6d0-920c-11ed-b36a-874bd1548a00] not found" + }, + "statusCode": { + "type": "integer", + "example": 404, + "enum": [ + 404 + ] + } + } + }, "update_rule_request": { "title": "Update rule request", "description": "The update rule API request body varies depending on the type of rule and actions.", @@ -1115,6 +1778,174 @@ } ] } + }, + "get_health_response": { + "summary": "Retrieve information about the health of the alerting framework.", + "value": { + "is_sufficiently_secure": true, + "has_permanent_encryption_key": true, + "alerting_framework_health": { + "decryption_health": { + "status": "ok", + "timestamp": "2023-01-13T01:28:00.280Z" + }, + "execution_health": { + "status": "ok", + "timestamp": "2023-01-13T01:28:00.280Z" + }, + "read_health": { + "status": "ok", + "timestamp": "2023-01-13T01:28:00.280Z" + } + }, + "alerting_framework_heath": { + "_deprecated": "This state property has a typo, use \"alerting_framework_health\" instead.", + "decryption_health": { + "status": "ok", + "timestamp": "2023-01-13T01:28:00.280Z" + }, + "execution_health": { + "status": "ok", + "timestamp": "2023-01-13T01:28:00.280Z" + }, + "read_health": { + "status": "ok", + "timestamp": "2023-01-13T01:28:00.280Z" + } + } + } + }, + "get_rule_types_response": { + "summary": "Retrieve rule types associated with Kibana machine learning features", + "value": [ + { + "id": "xpack.ml.anomaly_detection_alert", + "action_groups": [ + { + "id": "anomaly_score_match", + "name": "Anomaly score matched the condition" + }, + { + "id": "recovered", + "name": "Recovered" + } + ], + "action_variables": { + "context": [ + { + "name": "timestamp", + "description": "The bucket timestamp of the anomaly" + }, + { + "name": "timestampIso8601", + "description": "The bucket time of the anomaly in ISO8601 format" + }, + { + "name": "jobIds", + "description": "List of job IDs that triggered the alert" + }, + { + "name": "message", + "description": "Alert info message" + }, + { + "name": "isInterim", + "description": "Indicate if top hits contain interim results" + }, + { + "name": "score", + "description": "Anomaly score at the time of the notification action" + }, + { + "name": "topRecords", + "description": "Top records" + }, + { + "name": "topInfluencers", + "description": "Top influencers" + }, + { + "name": "anomalyExplorerUrl", + "description": "URL to open in the Anomaly Explorer", + "useWithTripleBracesInTemplates": true + } + ], + "params": [], + "state": [] + }, + "authorized_consumers": { + "alerts": { + "all": true, + "read": true + }, + "ml": { + "all": true, + "read": true + } + }, + "default_action_group_id": "anomaly_score_match", + "does_set_recovery_context": true, + "enabled_in_license": true, + "is_exportable": true, + "minimum_license_required": "platinum", + "name": "Anomaly detection alert", + "producer": "ml", + "recovery_action_group": { + "id": "recovered", + "name": "Recovered" + }, + "rule_task_timeout": "5m" + }, + { + "id": "xpack.ml.anomaly_detection_jobs_health", + "action_groups": [ + { + "id": "anomaly_detection_realtime_issue", + "name": "Issue detected" + }, + { + "id": "recovered", + "name": "Recovered" + } + ], + "action_variables": { + "context": [ + { + "name": "results", + "description": "Results of the rule execution" + }, + { + "name": "message", + "description": "Alert info message" + } + ], + "params": [], + "state": [] + }, + "authorized_consumers": { + "alerts": { + "all": true, + "read": true + }, + "ml": { + "all": true, + "read": true + } + }, + "default_action_group_id": "anomaly_detection_realtime_issue", + "does_set_recovery_context": true, + "enabled_in_license": true, + "is_exportable": true, + "minimum_license_required": "platinum", + "name": "Anomaly detection jobs health", + "producer": "ml", + "recovery_action_group": { + "id": "recovered", + "name": "Recovered" + }, + "rule_task_timeout": "5m" + } + ] } } }, diff --git a/x-pack/plugins/alerting/docs/openapi/bundled.yaml b/x-pack/plugins/alerting/docs/openapi/bundled.yaml index 029c6293557ce..95c0f0c266f1f 100644 --- a/x-pack/plugins/alerting/docs/openapi/bundled.yaml +++ b/x-pack/plugins/alerting/docs/openapi/bundled.yaml @@ -17,7 +17,7 @@ servers: paths: /s/{spaceId}/api/alerting/rule/{ruleId}: get: - summary: Retrieve a rule by its identifier. + summary: Retrieves a rule by its identifier. operationId: getRule description: | You must have `read` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rules you're seeking. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. To get rules associated with the **Stack Monitoring** feature, use the `monitoring_user` built-in role. @@ -34,8 +34,22 @@ paths: schema: $ref: '#/components/schemas/rule_response_properties' examples: - updateRuleResponse: + getRuleResponse: $ref: '#/components/examples/get_rule_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '#/components/schemas/404_response' + servers: + - url: https://localhost:5601 delete: summary: Deletes a rule. operationId: deleteRule @@ -50,6 +64,18 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '#/components/schemas/404_response' servers: - url: https://localhost:5601 put: @@ -82,13 +108,25 @@ paths: examples: updateRuleResponse: $ref: '#/components/examples/update_rule_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '#/components/schemas/404_response' servers: - url: https://localhost:5601 servers: - url: https://localhost:5601 /s/{spaceId}/api/alerting/rule/{ruleId}/_disable: post: - summary: Disable a rule. + summary: Disables a rule. operationId: disableRule description: | 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. @@ -101,13 +139,25 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '#/components/schemas/404_response' servers: - url: https://localhost:5601 servers: - url: https://localhost:5601 /s/{spaceId}/api/alerting/rule/{ruleId}/_enable: post: - summary: Enable a rule. + 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. @@ -120,6 +170,18 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' servers: - url: https://localhost:5601 servers: @@ -229,13 +291,331 @@ paths: examples: findRulesResponse: $ref: '#/components/examples/find_rules_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' servers: - url: https://localhost:5601 servers: - url: https://localhost:5601 + /s/{spaceId}/api/alerting/_health: + get: + summary: Retrieves the health status of the alerting framework. + operationId: getAlertingHealth + description: | + You must have `read` privileges for the **Management > Stack Rules** feature or for at least one of the **Analytics > Discover**, **Analytics > Machine Learning**, **Observability**, or **Security** features. + tags: + - alerting + parameters: + - $ref: '#/components/parameters/space_id' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + type: object + properties: + alerting_framework_heath: + type: object + description: This property has a typo. Use `alerting_framework_health` instead. + deprecated: true + properties: + _deprecated: + type: string + example: This state property has a typo, use "alerting_framework_health" instead. + decryption_health: + type: object + properties: + status: + type: string + example: ok + timestamp: + type: string + format: date-time + example: '2023-01-13T01:28:00.280Z' + execution_health: + type: object + properties: + status: + type: string + example: ok + timestamp: + type: string + format: date-time + example: '2023-01-13T01:28:00.280Z' + read_health: + type: object + properties: + status: + type: string + example: ok + timestamp: + type: string + format: date-time + example: '2023-01-13T01:28:00.280Z' + alerting_framework_health: + type: object + description: | + Three substates identify the health of the alerting framework: `decryption_health`, `execution_health`, and `read_health`. + properties: + decryption_health: + type: object + description: The timestamp and status of the rule decryption. + properties: + status: + type: string + example: ok + enum: + - error + - ok + - warn + timestamp: + type: string + format: date-time + example: '2023-01-13T01:28:00.280Z' + execution_health: + type: object + description: The timestamp and status of the rule run. + properties: + status: + type: string + example: ok + enum: + - error + - ok + - warn + timestamp: + type: string + format: date-time + example: '2023-01-13T01:28:00.280Z' + read_health: + type: object + description: The timestamp and status of the rule reading events. + properties: + status: + type: string + example: ok + enum: + - error + - ok + - warn + timestamp: + type: string + format: date-time + example: '2023-01-13T01:28:00.280Z' + has_permanent_encryption_key: + type: boolean + description: If `false`, the encrypted saved object plugin does not have a permanent encryption key. + example: true + is_sufficiently_secure: + type: boolean + description: If `false`, security is enabled but TLS is not. + example: true + examples: + getAlertingHealthResponse: + $ref: '#/components/examples/get_health_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + servers: + - url: https://localhost:5601 + /s/{spaceId}/api/alerting/rule_types: + get: + summary: Retrieves a list of rule types. + operationId: getRuleTypes + description: | + If you have `read` privileges for one or more Kibana features, the API response contains information about the appropriate rule types. For example, there are rule types associated with the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, and **Security** features. To get rule types associated with the **Stack Monitoring** feature, use the `monitoring_user` built-in role. + tags: + - alerting + parameters: + - $ref: '#/components/parameters/space_id' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + type: array + items: + type: object + properties: + action_groups: + description: | + An explicit list of groups for which the rule type can schedule actions, each with the action group's unique ID and human readable name. Rule actions validation uses this configuration to ensure that groups are valid. + type: array + items: + type: object + properties: + id: + type: string + name: + type: string + action_variables: + description: | + A list of action variables that the rule type makes available via context and state in action parameter templates, and a short human readable description. When you create a rule in Kibana, it uses this information to prompt you for these variables in action parameter editors. + type: object + properties: + context: + type: array + items: + type: object + properties: + name: + type: string + description: + type: string + useWithTripleBracesInTemplates: + type: boolean + params: + type: array + items: + type: object + properties: + description: + type: string + name: + type: string + state: + type: array + items: + type: object + properties: + description: + type: string + name: + type: string + authorized_consumers: + description: The list of the plugins IDs that have access to the rule type. + type: object + properties: + alerts: + type: object + properties: + all: + type: boolean + read: + type: boolean + apm: + type: object + properties: + all: + type: boolean + read: + type: boolean + discover: + type: object + properties: + all: + type: boolean + read: + type: boolean + infrastructure: + type: object + properties: + all: + type: boolean + read: + type: boolean + logs: + type: object + properties: + all: + type: boolean + read: + type: boolean + ml: + type: object + properties: + all: + type: boolean + read: + type: boolean + monitoring: + type: object + properties: + all: + type: boolean + read: + type: boolean + siem: + type: object + properties: + all: + type: boolean + read: + type: boolean + stackAlerts: + type: object + properties: + all: + type: boolean + read: + type: boolean + uptime: + type: object + properties: + all: + type: boolean + read: + type: boolean + default_action_group_id: + description: The default identifier for the rule type group. + type: string + does_set_recovery_context: + description: Indicates whether the rule passes context variables to its recovery action. + type: boolean + enabled_in_license: + description: Indicates whether the rule type is enabled or disabled based on the subscription. + type: boolean + id: + description: The unique identifier for the rule type. + type: string + is_exportable: + description: Indicates whether the rule type is exportable in **Stack Management > Saved Objects**. + type: boolean + minimum_license_required: + description: The subscriptions required to use the rule type. + type: string + example: basic + name: + description: The descriptive name of the rule type. + type: string + producer: + description: An identifier for the application that produces this rule type. + type: string + example: stackAlerts + recovery_action_group: + description: An action group to use when an alert goes from an active state to an inactive one. + type: object + properties: + id: + type: string + name: + type: string + rule_task_timeout: + type: string + example: 5m + examples: + getRuleTypesResponse: + $ref: '#/components/examples/get_rule_types_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + servers: + - url: https://localhost:5601 /s/{spaceId}/api/alerting/rule/{ruleId}/_mute_all: post: - summary: Mute all alerts. + summary: Mutes all alerts. operationId: muteAllAlerts description: | This API snoozes the notifications for the rule indefinitely. The rule checks continue to occur but alerts will not trigger any actions. 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. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. @@ -248,13 +628,19 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' servers: - url: https://localhost:5601 servers: - url: https://localhost:5601 /s/{spaceId}/api/alerting/rule/{ruleId}/_unmute_all: post: - summary: Unmute all alerts. + summary: Unmutes all alerts. operationId: unmuteAllAlerts description: | If the rule has its notifications snoozed indefinitely, this API cancels the snooze. 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. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. @@ -267,13 +653,19 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' servers: - url: https://localhost:5601 servers: - url: https://localhost:5601 /s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_mute: post: - summary: Mute an alert. + summary: Mutes an alert. operationId: muteAlert description: | 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. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. @@ -287,13 +679,19 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' servers: - url: https://localhost:5601 servers: - url: https://localhost:5601 /s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_unmute: post: - summary: Unmute an alert. + summary: Unmutes an alert. operationId: unmuteAlert description: | 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. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. @@ -307,6 +705,12 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' servers: - url: https://localhost:5601 servers: @@ -539,6 +943,38 @@ components: description: The identifier for the user that updated this rule most recently. nullable: true example: elastic + 401_response: + type: object + title: Unsuccessful rule API response + properties: + error: + type: string + example: Unauthorized + enum: + - Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + enum: + - 401 + 404_response: + type: object + properties: + error: + type: string + example: Not Found + enum: + - Not Found + message: + type: string + example: Saved object [alert/caaad6d0-920c-11ed-b36a-874bd1548a00] not found + statusCode: + type: integer + example: 404 + enum: + - 404 update_rule_request: title: Update rule request description: The update rule API request body varies depending on the type of rule and actions. @@ -770,6 +1206,114 @@ components: warning: null outcome: succeeded next_run: '2022-12-06T01:45:23.912Z' + get_health_response: + summary: Retrieve information about the health of the alerting framework. + value: + is_sufficiently_secure: true + has_permanent_encryption_key: true + alerting_framework_health: + decryption_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + execution_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + read_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + alerting_framework_heath: + _deprecated: This state property has a typo, use "alerting_framework_health" instead. + decryption_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + execution_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + read_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + get_rule_types_response: + summary: Retrieve rule types associated with Kibana machine learning features + value: + - id: xpack.ml.anomaly_detection_alert + action_groups: + - id: anomaly_score_match + name: Anomaly score matched the condition + - id: recovered + name: Recovered + action_variables: + context: + - name: timestamp + description: The bucket timestamp of the anomaly + - name: timestampIso8601 + description: The bucket time of the anomaly in ISO8601 format + - name: jobIds + description: List of job IDs that triggered the alert + - name: message + description: Alert info message + - name: isInterim + description: Indicate if top hits contain interim results + - name: score + description: Anomaly score at the time of the notification action + - name: topRecords + description: Top records + - name: topInfluencers + description: Top influencers + - name: anomalyExplorerUrl + description: URL to open in the Anomaly Explorer + useWithTripleBracesInTemplates: true + params: [] + state: [] + authorized_consumers: + alerts: + all: true + read: true + ml: + all: true + read: true + default_action_group_id: anomaly_score_match + does_set_recovery_context: true + enabled_in_license: true + is_exportable: true + minimum_license_required: platinum + name: Anomaly detection alert + producer: ml + recovery_action_group: + id: recovered + name: Recovered + rule_task_timeout: 5m + - id: xpack.ml.anomaly_detection_jobs_health + action_groups: + - id: anomaly_detection_realtime_issue + name: Issue detected + - id: recovered + name: Recovered + action_variables: + context: + - name: results + description: Results of the rule execution + - name: message + description: Alert info message + params: [] + state: [] + authorized_consumers: + alerts: + all: true + read: true + ml: + all: true + read: true + default_action_group_id: anomaly_detection_realtime_issue + does_set_recovery_context: true + enabled_in_license: true + is_exportable: true + minimum_license_required: platinum + name: Anomaly detection jobs health + producer: ml + recovery_action_group: + id: recovered + name: Recovered + rule_task_timeout: 5m security: - basicAuth: [] - apiKeyAuth: [] diff --git a/x-pack/plugins/alerting/docs/openapi/components/examples/get_health_response.yaml b/x-pack/plugins/alerting/docs/openapi/components/examples/get_health_response.yaml new file mode 100644 index 0000000000000..fcd334cc677cf --- /dev/null +++ b/x-pack/plugins/alerting/docs/openapi/components/examples/get_health_response.yaml @@ -0,0 +1,25 @@ +summary: Retrieve information about the health of the alerting framework. +value: + is_sufficiently_secure: true + has_permanent_encryption_key: true + alerting_framework_health: + decryption_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + execution_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + read_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + alerting_framework_heath: + _deprecated: "This state property has a typo, use \"alerting_framework_health\" instead." + decryption_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + execution_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + read_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/examples/get_rule_types_response.yaml b/x-pack/plugins/alerting/docs/openapi/components/examples/get_rule_types_response.yaml new file mode 100644 index 0000000000000..8299f7357a217 --- /dev/null +++ b/x-pack/plugins/alerting/docs/openapi/components/examples/get_rule_types_response.yaml @@ -0,0 +1,81 @@ +summary: Retrieve rule types associated with Kibana machine learning features +value: + - id: xpack.ml.anomaly_detection_alert + action_groups: + - id: anomaly_score_match + name: Anomaly score matched the condition + - id: recovered + name: Recovered + action_variables: + context: + - name: timestamp + description: The bucket timestamp of the anomaly + - name: timestampIso8601 + description: The bucket time of the anomaly in ISO8601 format + - name: jobIds + description: List of job IDs that triggered the alert + - name: message + description: Alert info message + - name: isInterim + description: Indicate if top hits contain interim results + - name: score + description: Anomaly score at the time of the notification action + - name: topRecords + description: Top records + - name: topInfluencers + description: Top influencers + - name: anomalyExplorerUrl + description: URL to open in the Anomaly Explorer + useWithTripleBracesInTemplates: true + params: [] + state: [] + authorized_consumers: + alerts: + all: true + read: true + ml: + all: true + read: true + default_action_group_id: anomaly_score_match + does_set_recovery_context: true + enabled_in_license: true + is_exportable: true + minimum_license_required: platinum + name: Anomaly detection alert + producer: ml + recovery_action_group: + id: recovered + name: Recovered + rule_task_timeout: 5m + - id: xpack.ml.anomaly_detection_jobs_health + action_groups: + - id: anomaly_detection_realtime_issue + name: Issue detected + - id: recovered + name: Recovered + action_variables: + context: + - name: results + description: Results of the rule execution + - name: message + description: Alert info message + params: [] + state: [] + authorized_consumers: + alerts: + all: true + read: true + ml: + all: true + read: true + default_action_group_id: anomaly_detection_realtime_issue + does_set_recovery_context: true + enabled_in_license: true + is_exportable: true + minimum_license_required: platinum + name: Anomaly detection jobs health + producer: ml + recovery_action_group: + id: recovered + name: Recovered + rule_task_timeout: 5m diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/401_response.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/401_response.yaml new file mode 100644 index 0000000000000..c6044998f8649 --- /dev/null +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/401_response.yaml @@ -0,0 +1,15 @@ +type: object +title: Unsuccessful rule API response +properties: + error: + type: string + example: Unauthorized + enum: + - Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + enum: + - 401 \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/404_response.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/404_response.yaml new file mode 100644 index 0000000000000..1b8a118703ecb --- /dev/null +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/404_response.yaml @@ -0,0 +1,15 @@ +type: object +properties: + error: + type: string + example: Not Found + enum: + - Not Found + message: + type: string + example: "Saved object [alert/caaad6d0-920c-11ed-b36a-874bd1548a00] not found" + statusCode: + type: integer + example: 404 + enum: + - 404 \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/entrypoint.yaml b/x-pack/plugins/alerting/docs/openapi/entrypoint.yaml index b26443cfc8dce..3b141954b30da 100644 --- a/x-pack/plugins/alerting/docs/openapi/entrypoint.yaml +++ b/x-pack/plugins/alerting/docs/openapi/entrypoint.yaml @@ -23,10 +23,10 @@ paths: $ref: 'paths/s@{spaceid}@api@alerting@rule@{ruleid}@_enable.yaml' '/s/{spaceId}/api/alerting/rules/_find': $ref: 'paths/s@{spaceid}@api@alerting@rules@_find.yaml' -# '/s/{spaceId}/api/alerting/_health': -# $ref: paths/s@{spaceid}@api@alerting@_health.yaml -# '/s/{spaceId}/api/alerting/rule_types': -# $ref: 'paths/s@{spaceid}@api@alerting@rule_types.yaml' + '/s/{spaceId}/api/alerting/_health': + $ref: paths/s@{spaceid}@api@alerting@_health.yaml + '/s/{spaceId}/api/alerting/rule_types': + $ref: 'paths/s@{spaceid}@api@alerting@rule_types.yaml' '/s/{spaceId}/api/alerting/rule/{ruleId}/_mute_all': $ref: 'paths/s@{spaceid}@api@alerting@rule@{ruleid}@_mute_all.yaml' '/s/{spaceId}/api/alerting/rule/{ruleId}/_unmute_all': diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@_health.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@_health.yaml new file mode 100644 index 0000000000000..6934bddfa9580 --- /dev/null +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@_health.yaml @@ -0,0 +1,126 @@ +get: + summary: Retrieves the health status of the alerting framework. + operationId: getAlertingHealth + description: > + You must have `read` privileges for the **Management > Stack Rules** feature + or for at least one of the **Analytics > Discover**, + **Analytics > Machine Learning**, **Observability**, or **Security** features. + tags: + - alerting + parameters: + - $ref: '../components/parameters/space_id.yaml' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + type: object + properties: + alerting_framework_heath: + type: object + description: This property has a typo. Use `alerting_framework_health` instead. + deprecated: true + properties: + _deprecated: + type: string + example: "This state property has a typo, use \"alerting_framework_health\" instead." + decryption_health: + type: object + properties: + status: + type: string + example: ok + timestamp: + type: string + format: date-time + example: "2023-01-13T01:28:00.280Z" + execution_health: + type: object + properties: + status: + type: string + example: ok + timestamp: + type: string + format: date-time + example: "2023-01-13T01:28:00.280Z" + read_health: + type: object + properties: + status: + type: string + example: ok + timestamp: + type: string + format: date-time + example: "2023-01-13T01:28:00.280Z" + alerting_framework_health: + type: object + description: > + Three substates identify the health of the alerting framework: `decryption_health`, `execution_health`, and `read_health`. + properties: + decryption_health: + type: object + description: The timestamp and status of the rule decryption. + properties: + status: + type: string + example: ok + enum: + - error + - ok + - warn + timestamp: + type: string + format: date-time + example: "2023-01-13T01:28:00.280Z" + execution_health: + type: object + description: The timestamp and status of the rule run. + properties: + status: + type: string + example: ok + enum: + - error + - ok + - warn + timestamp: + type: string + format: date-time + example: "2023-01-13T01:28:00.280Z" + read_health: + type: object + description: The timestamp and status of the rule reading events. + properties: + status: + type: string + example: ok + enum: + - error + - ok + - warn + timestamp: + type: string + format: date-time + example: "2023-01-13T01:28:00.280Z" + has_permanent_encryption_key: + type: boolean + description: If `false`, the encrypted saved object plugin does not have a permanent encryption key. + example: true + is_sufficiently_secure: + type: boolean + description: If `false`, security is enabled but TLS is not. + example: true + examples: + getAlertingHealthResponse: + $ref: '../components/examples/get_health_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' +servers: + - url: https://localhost:5601 \ No newline at end of file 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 cb6a4a34525d9..91ef40aa0c2e9 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 @@ -1,5 +1,5 @@ get: - summary: Retrieve a rule by its identifier. + summary: Retrieves a rule by its identifier. operationId: getRule description: > You must have `read` privileges for the appropriate Kibana features, @@ -21,8 +21,22 @@ get: schema: $ref: '../components/schemas/rule_response_properties.yaml' examples: - updateRuleResponse: + getRuleResponse: $ref: '../components/examples/get_rule_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '../components/schemas/404_response.yaml' + servers: + - url: https://localhost:5601 delete: summary: Deletes a rule. @@ -42,6 +56,18 @@ delete: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '../components/schemas/404_response.yaml' servers: - url: https://localhost:5601 @@ -88,6 +114,18 @@ put: examples: updateRuleResponse: $ref: '../components/examples/update_rule_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '../components/schemas/404_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_disable.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_disable.yaml index 8c8a60ae2ce2e..d0d5321a48420 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_disable.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_disable.yaml @@ -1,5 +1,5 @@ post: - summary: Disable a rule. + summary: Disables a rule. operationId: disableRule description: > You must have `all` privileges for the appropriate Kibana features, @@ -15,6 +15,18 @@ post: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '../components/schemas/404_response.yaml' servers: - url: https://localhost:5601 servers: 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 ee4ef54fc43f6..cb7991c2d9185 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 @@ -1,5 +1,5 @@ post: - summary: Enable a rule. + summary: Enables a rule. operationId: enableRule description: > This API supports token-based authentication only. @@ -16,6 +16,18 @@ post: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_mute_all.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_mute_all.yaml index a816ed0b0b7ef..00250d5a754a4 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_mute_all.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_mute_all.yaml @@ -1,5 +1,5 @@ post: - summary: Mute all alerts. + summary: Mutes all alerts. operationId: muteAllAlerts description: > This API snoozes the notifications for the rule indefinitely. The rule @@ -19,6 +19,12 @@ post: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_unmute_all.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_unmute_all.yaml index 38e8f0807c998..b0a887e7b427e 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_unmute_all.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_unmute_all.yaml @@ -1,5 +1,5 @@ post: - summary: Unmute all alerts. + summary: Unmutes all alerts. operationId: unmuteAllAlerts description: > If the rule has its notifications snoozed indefinitely, this API cancels the snooze. @@ -18,6 +18,12 @@ post: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_mute.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_mute.yaml index d120c06e7a6c4..2356bf4a60394 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_mute.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_mute.yaml @@ -1,5 +1,5 @@ post: - summary: Mute an alert. + summary: Mutes an alert. operationId: muteAlert description: > You must have `all` privileges for the appropriate Kibana features, @@ -18,6 +18,12 @@ post: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_unmute.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_unmute.yaml index bbc92453e236b..c06eccb531b46 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_unmute.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_unmute.yaml @@ -1,5 +1,5 @@ post: - summary: Unmute an alert. + summary: Unmutes an alert. operationId: unmuteAlert description: > You must have `all` privileges for the appropriate Kibana features, @@ -18,6 +18,12 @@ post: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule_types.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule_types.yaml new file mode 100644 index 0000000000000..8b7019ee54539 --- /dev/null +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule_types.yaml @@ -0,0 +1,198 @@ +get: + summary: Retrieves a list of rule types. + operationId: getRuleTypes + description: > + If you have `read` privileges for one or more Kibana features, the API + response contains information about the appropriate rule types. For example, + there are rule types associated with the **Management > Stack Rules** feature, + **Analytics > Discover** and **Machine Learning** features, **Observability** + features, and **Security** features. To get rule types associated with the + **Stack Monitoring** feature, use the `monitoring_user` built-in role. + tags: + - alerting + parameters: + - $ref: '../components/parameters/space_id.yaml' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + type: array + items: + type: object + properties: + action_groups: + description: > + An explicit list of groups for which the rule type can + schedule actions, each with the action group's unique ID and + human readable name. Rule actions validation uses this + configuration to ensure that groups are valid. + type: array + items: + type: object + properties: + id: + type: string + name: + type: string + action_variables: + description: > + A list of action variables that the rule type makes available + via context and state in action parameter templates, and a + short human readable description. When you create a rule in + Kibana, it uses this information to prompt you for these + variables in action parameter editors. + type: object + properties: + context: + type: array + items: + type: object + properties: + name: + type: string + description: + type: string + useWithTripleBracesInTemplates: + type: boolean + params: + type: array + items: + type: object + properties: + description: + type: string + name: + type: string + state: + type: array + items: + type: object + properties: + description: + type: string + name: + type: string + authorized_consumers: + description: The list of the plugins IDs that have access to the rule type. + type: object + properties: + alerts: + type: object + properties: + all: + type: boolean + read: + type: boolean + apm: + type: object + properties: + all: + type: boolean + read: + type: boolean + discover: + type: object + properties: + all: + type: boolean + read: + type: boolean + infrastructure: + type: object + properties: + all: + type: boolean + read: + type: boolean + logs: + type: object + properties: + all: + type: boolean + read: + type: boolean + ml: + type: object + properties: + all: + type: boolean + read: + type: boolean + monitoring: + type: object + properties: + all: + type: boolean + read: + type: boolean + siem: + type: object + properties: + all: + type: boolean + read: + type: boolean + stackAlerts: + type: object + properties: + all: + type: boolean + read: + type: boolean + uptime: + type: object + properties: + all: + type: boolean + read: + type: boolean + default_action_group_id: + description: The default identifier for the rule type group. + type: string + does_set_recovery_context: + description: Indicates whether the rule passes context variables to its recovery action. + type: boolean + enabled_in_license: + description: Indicates whether the rule type is enabled or disabled based on the subscription. + type: boolean + id: + description: The unique identifier for the rule type. + type: string + is_exportable: + description: Indicates whether the rule type is exportable in **Stack Management > Saved Objects**. + type: boolean + minimum_license_required: + description: The subscriptions required to use the rule type. + type: string + example: basic + name: + description: The descriptive name of the rule type. + type: string + producer: + description: An identifier for the application that produces this rule type. + type: string + example: stackAlerts + recovery_action_group: + description: An action group to use when an alert goes from an active state to an inactive one. + type: object + properties: + id: + type: string + name: + type: string + rule_task_timeout: + type: string + example: 5m + examples: + getRuleTypesResponse: + $ref: '../components/examples/get_rule_types_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' +servers: + - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rules@_find.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rules@_find.yaml index 42c4b817f7968..2f84059aa392d 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rules@_find.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rules@_find.yaml @@ -113,6 +113,12 @@ get: examples: findRulesResponse: $ref: '../components/examples/find_rules_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' servers: - url: https://localhost:5601 servers: From 05a3e27a6b1550529474e917e6e65d1090e24e31 Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Tue, 17 Jan 2023 12:02:38 -0600 Subject: [PATCH 09/44] [Enterprise Search] Engines pagination fix (#148947) ## Summary Fixing calculation for the pagination on the Engines list page. Fixing the rendering of engine index source on the engine indices page. --- .../components/engine/engine_indices.tsx | 6 +-- .../engines/engine_list_logic.test.ts | 48 +++++++++++++------ .../components/engines/engines_list.tsx | 14 +++--- .../components/engines/engines_list_logic.ts | 12 +++-- .../components/engines/types.ts | 14 +++--- .../utils/indices.ts | 36 ++++++++------ 6 files changed, 79 insertions(+), 51 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engine/engine_indices.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engine/engine_indices.tsx index 7168f37c8b678..537c83cac5b1e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engine/engine_indices.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engine/engine_indices.tsx @@ -92,15 +92,15 @@ export const EngineIndices: React.FC = () => { width: '15%', }, { - field: 'ingestionMethod', + field: 'source', name: i18n.translate( 'xpack.enterpriseSearch.content.engine.indices.ingestionMethod.columnTitle', { defaultMessage: 'Ingestion method', } ), - render: (ingestionMethod: IngestionMethod) => ( - {ingestionMethodToText(ingestionMethod)} + render: (source: IngestionMethod) => ( + {ingestionMethodToText(source)} ), truncateText: true, width: '15%', diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engine_list_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engine_list_logic.test.ts index a88203f81ea9e..e6128bab79bb6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engine_list_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engine_list_logic.test.ts @@ -71,21 +71,39 @@ describe('EnginesListLogic', () => { describe('onPaginate', () => { it('updates meta with newPageIndex', () => { expect(EnginesListLogic.values).toEqual(DEFAULT_VALUES); - // test below code when pagination is ready - // EnginesListLogic.actions.onPaginate(1); - // expect(EnginesListLogic.values).toEqual({ - // ...DEFAULT_VALUES, - // meta: { - // ...DEFAULT_META, - // from: 1, - // }, - // parameters: { - // meta: { - // ...DEFAULT_META, - // from: 1, - // }, - // }, - // }); + + EnginesListLogic.actions.onPaginate({ page: { index: 1 } }); + expect(EnginesListLogic.values).toEqual({ + ...DEFAULT_VALUES, + meta: { + ...DEFAULT_META, + from: 10, + }, + parameters: { + meta: { + ...DEFAULT_META, + from: 10, + }, + }, + }); + + EnginesListLogic.actions.onPaginate({ page: { index: 0 } }); + expect(EnginesListLogic.values).toEqual(DEFAULT_VALUES); + + EnginesListLogic.actions.onPaginate({ page: { index: 3 } }); + expect(EnginesListLogic.values).toEqual({ + ...DEFAULT_VALUES, + meta: { + ...DEFAULT_META, + from: 30, + }, + parameters: { + meta: { + ...DEFAULT_META, + from: 30, + }, + }, + }); }); }); describe('closeDeleteEngineModal', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list.tsx index 51eb674764066..7ca7c0994e4e4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list.tsx @@ -16,8 +16,6 @@ import { FormattedMessage, FormattedNumber } from '@kbn/i18n-react'; import { DataPanel } from '../../../shared/data_panel/data_panel'; -import { handlePageChange } from '../../../shared/table_pagination'; - import { EnterpriseSearchContentPageTemplate } from '../layout/page_template'; import { EnginesListTable } from './components/tables/engines_table'; @@ -121,16 +119,16 @@ export const EnginesList: React.FC = () => { - + ), - size: ( + to: ( - + ), total: , @@ -149,7 +147,7 @@ export const EnginesList: React.FC = () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list_logic.ts index 4d58ff95bc15a..8f7a012518905 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list_logic.ts @@ -28,13 +28,17 @@ import { import { DEFAULT_META, Meta, updateMetaPageIndex } from './types'; +interface EuiBasicTableOnChange { + page: { index: number }; +} + type EnginesListActions = Pick< Actions, 'apiError' | 'apiSuccess' | 'makeRequest' > & { closeDeleteEngineModal(): void; - deleteError: DeleteEnginesApiLogicActions['apiError']; deleteEngine: DeleteEnginesApiLogicActions['makeRequest']; + deleteError: DeleteEnginesApiLogicActions['apiError']; deleteSuccess: DeleteEnginesApiLogicActions['apiSuccess']; fetchEngines({ meta, searchQuery }: { meta: Meta; searchQuery?: string }): { @@ -42,17 +46,17 @@ type EnginesListActions = Pick< searchQuery?: string; }; + onPaginate(args: EuiBasicTableOnChange): { pageNumber: number }; openDeleteEngineModal: (engine: EnterpriseSearchEngine) => { engine: EnterpriseSearchEngine }; - onPaginate(pageNumber: number): { pageNumber: number }; }; interface EngineListValues { data: typeof FetchEnginesAPILogic.values.data; deleteModalEngine: EnterpriseSearchEngine | null; deleteModalEngineName: string; deleteStatus: typeof DeleteEngineAPILogic.values.status; - isLoading: boolean; isDeleteLoading: boolean; isDeleteModalVisible: boolean; + isLoading: boolean; meta: Meta; parameters: { meta: Meta; searchQuery?: string }; // Added this variable to store to the search Query value as well results: EnterpriseSearchEngine[]; // stores engine list value from data @@ -80,8 +84,8 @@ export const EnginesListLogic = kea ({ pageNumber: args.page.index }), openDeleteEngineModal: (engine) => ({ engine }), - onPaginate: (pageNumber) => ({ pageNumber }), }, path: ['enterprise_search', 'content', 'engine_list_logic'], reducers: ({}) => ({ diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/types.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/types.ts index 2dc0b2f7fe335..90fb49a054688 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/types.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/types.ts @@ -17,11 +17,13 @@ export const DEFAULT_META = { total: 0, }; -export const convertMetaToPagination = (meta: Meta) => ({ - pageIndex: meta.from - 1, - pageSize: meta.size, - totalItemCount: meta.total, -}); +export const convertMetaToPagination = (meta: Meta) => { + return { + pageIndex: meta.from / meta.size, + pageSize: meta.size, + totalItemCount: meta.total, + }; +}; export const updateMetaPageIndex = (oldState: Meta, newPageIndex: number) => { - return { ...oldState, from: newPageIndex }; + return { ...oldState, from: newPageIndex * oldState.size }; }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/indices.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/indices.ts index 3bc19bb2a8b65..fd87b60bd99a8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/indices.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/indices.ts @@ -129,20 +129,26 @@ export function indexToViewIndex(index: ElasticsearchIndex): ApiViewIndex { } export function ingestionMethodToText(ingestionMethod: IngestionMethod) { - if (ingestionMethod === IngestionMethod.CONNECTOR) { - return i18n.translate( - 'xpack.enterpriseSearch.content.searchIndices.ingestionMethod.connector', - { - defaultMessage: 'Connector', - } - ); + switch (ingestionMethod) { + case IngestionMethod.CONNECTOR: + return i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.ingestionMethod.connector', + { + defaultMessage: 'Connector', + } + ); + case IngestionMethod.CRAWLER: + return i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.ingestionMethod.crawler', + { + defaultMessage: 'Crawler', + } + ); + case IngestionMethod.API: + return i18n.translate('xpack.enterpriseSearch.content.searchIndices.ingestionMethod.api', { + defaultMessage: 'API', + }); + default: + return ingestionMethod; } - if (ingestionMethod === IngestionMethod.CRAWLER) { - return i18n.translate('xpack.enterpriseSearch.content.searchIndices.ingestionMethod.crawler', { - defaultMessage: 'Crawler', - }); - } - return i18n.translate('xpack.enterpriseSearch.content.searchIndices.ingestionMethod.api', { - defaultMessage: 'API', - }); } From 75c2cfdd22b1edda72dc86f1b21fbbb87f3289a4 Mon Sep 17 00:00:00 2001 From: Johannes Mahne Date: Tue, 17 Jan 2023 20:28:03 +0200 Subject: [PATCH 10/44] =?UTF-8?q?Adding=20clarification=20to=20the=20use?= =?UTF-8?q?=20of=20the=20environment=20variable=20in=20the=20Ma=E2=80=A6?= =?UTF-8?q?=20(#145847)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …p Service Adding some text to help clear out confusion by users reading the `EMS_PATH_CONF` env variable as a host env var, instead of a env variable inside the docker container. Also, mentioning the `-e` docker flag that can be used on the docker command to start up the service. ## Summary Summarize your PR. If it involves visual changes include a screenshot or gif. ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### Risk Matrix Delete this section if it is not applicable to this PR. Before closing this PR, invite QA, stakeholders, and other developers to identify risks that should be tested prior to the change/feature release. When forming the risk matrix, consider some of the following examples and how they may potentially impact the change: | Risk | Probability | Severity | Mitigation/Notes | |---------------------------|-------------|----------|-------------------------| | Multiple Spaces—unexpected behavior in non-default Kibana Space. | Low | High | Integration tests will verify that all features are still supported in non-default Kibana Space and when user switches between spaces. | | Multiple nodes—Elasticsearch polling might have race conditions when multiple Kibana nodes are polling for the same tasks. | High | Low | Tasks are idempotent, so executing them multiple times will not result in logical error, but will degrade performance. To test for this case we add plenty of unit tests around this logic and document manual testing procedure. | | Code should gracefully handle cases when feature X or plugin Y are disabled. | Medium | High | Unit tests will verify that any feature flag or plugin combination still results in our service operational. | | [See more potential risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) | ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- docs/maps/connect-to-ems.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/maps/connect-to-ems.asciidoc b/docs/maps/connect-to-ems.asciidoc index f3e0709f7f506..6a2ed12d9c536 100644 --- a/docs/maps/connect-to-ems.asciidoc +++ b/docs/maps/connect-to-ems.asciidoc @@ -66,7 +66,7 @@ endif::[] [[elastic-maps-server-configuration]] ==== Configuration -{hosted-ems} reads properties from a configuration file in YAML format that is validated on startup. The location of this file is provided by the `EMS_PATH_CONF` environment variable and defaults to `/usr/src/app/server/config/elastic-maps-server.yml`. +{hosted-ems} reads properties from a configuration file in YAML format that is validated on startup. The location of this file is provided by the `EMS_PATH_CONF` container environment variable and defaults to `/usr/src/app/server/config/elastic-maps-server.yml`. This environment variable can be changed by making use of the `-e` docker flag of the start command. *General settings* From 9d571d9e0e8a69ceceb5dcac8646c7e28efae446 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Tue, 17 Jan 2023 12:42:33 -0600 Subject: [PATCH 11/44] skip suite failing es promotion (#149068) --- x-pack/test/api_integration/apis/maps/get_grid_tile.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/api_integration/apis/maps/get_grid_tile.js b/x-pack/test/api_integration/apis/maps/get_grid_tile.js index 6f35ca27cb926..0b3a454da814c 100644 --- a/x-pack/test/api_integration/apis/maps/get_grid_tile.js +++ b/x-pack/test/api_integration/apis/maps/get_grid_tile.js @@ -21,7 +21,8 @@ function findFeature(layer, callbackFn) { export default function ({ getService }) { const supertest = getService('supertest'); - describe('getGridTile', () => { + // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/149068 + describe.skip('getGridTile', () => { const URL = `/api/maps/mvt/getGridTile/3/2/3.pbf\ ?geometryFieldName=geo.coordinates\ &hasLabels=false\ From 3d843e2875748f030771daf56d2d78a557136e07 Mon Sep 17 00:00:00 2001 From: Dmitrii Shevchenko Date: Tue, 17 Jan 2023 19:52:09 +0100 Subject: [PATCH 12/44] [Security Solution] Add support for Fleet packages with historical rule versions (#148643) **Resolves: https://github.com/elastic/kibana/issues/148179** --- .../route.test.ts | 4 +- .../route.ts | 6 +- .../route.ts | 4 +- .../prebuilt_rules/api/register_routes.ts | 4 +- .../logic/get_latest_prebuilt_rules.ts | 23 ++---- .../rule_asset_saved_objects_client.ts | 79 ++++++++++++------- .../security_solution/server/routes/index.ts | 2 +- 7 files changed, 64 insertions(+), 58 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.test.ts index fd7351c677a2a..3d3accea3fa24 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.test.ts @@ -12,7 +12,7 @@ import { getFindResultWithSingleHit, getPrepackagedRulesStatusRequest, } from '../../../routes/__mocks__/request_responses'; -import { requestContextMock, serverMock, createMockConfig } from '../../../routes/__mocks__'; +import { requestContextMock, serverMock } from '../../../routes/__mocks__'; import type { SecurityPluginSetup } from '@kbn/security-plugin/server'; import { checkTimelinesStatus } from '../../../../timeline/utils/check_timelines_status'; import { @@ -82,7 +82,7 @@ describe('get_prepackaged_rule_status_route', () => { prepackagedTimelines: [], }); - getPrebuiltRulesAndTimelinesStatusRoute(server.router, createMockConfig(), securitySetup); + getPrebuiltRulesAndTimelinesStatusRoute(server.router, securitySetup); }); describe('status codes', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.ts index c765ed4ab6cc3..ced2a0e8ea663 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.ts @@ -8,7 +8,6 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { validate } from '@kbn/securitysolution-io-ts-utils'; import { buildSiemResponse } from '../../../routes/utils'; -import type { ConfigType } from '../../../../../config'; import type { SetupPlugins } from '../../../../../plugin'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; @@ -22,7 +21,7 @@ import { findRules } from '../../../rule_management/logic/search/find_rules'; import { getLatestPrebuiltRules } from '../../logic/get_latest_prebuilt_rules'; import { getRulesToInstall } from '../../logic/get_rules_to_install'; import { getRulesToUpdate } from '../../logic/get_rules_to_update'; -import { ruleAssetSavedObjectsClientFactory } from '../../logic/rule_asset/rule_asset_saved_objects_client'; +import { ruleAssetsClientFactory } from '../../logic/rule_asset/rule_asset_saved_objects_client'; import { rulesToMap } from '../../logic/utils'; import { buildFrameworkRequest } from '../../../../timeline/utils/common'; @@ -33,7 +32,6 @@ import { export const getPrebuiltRulesAndTimelinesStatusRoute = ( router: SecuritySolutionPluginRouter, - config: ConfigType, security: SetupPlugins['security'] ) => { router.get( @@ -49,7 +47,7 @@ export const getPrebuiltRulesAndTimelinesStatusRoute = ( const ctx = await context.resolve(['core', 'alerting']); const savedObjectsClient = ctx.core.savedObjects.client; const rulesClient = ctx.alerting.getRulesClient(); - const ruleAssetsClient = ruleAssetSavedObjectsClientFactory(savedObjectsClient); + const ruleAssetsClient = ruleAssetsClientFactory(savedObjectsClient); try { const latestPrebuiltRules = await getLatestPrebuiltRules(ruleAssetsClient); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/route.ts index 2eca0146dc8a7..d2aa7216404d2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/route.ts @@ -27,7 +27,7 @@ import { createPrebuiltRules } from '../../logic/create_prebuilt_rules'; import { updatePrebuiltRules } from '../../logic/update_prebuilt_rules'; import { getRulesToInstall } from '../../logic/get_rules_to_install'; import { getRulesToUpdate } from '../../logic/get_rules_to_update'; -import { ruleAssetSavedObjectsClientFactory } from '../../logic/rule_asset/rule_asset_saved_objects_client'; +import { ruleAssetsClientFactory } from '../../logic/rule_asset/rule_asset_saved_objects_client'; import { rulesToMap } from '../../logic/utils'; import { installPrepackagedTimelines } from '../../../../timeline/routes/prepackaged_timelines/install_prepackaged_timelines'; @@ -90,7 +90,7 @@ export const createPrepackagedRules = async ( const savedObjectsClient = context.core.savedObjects.client; const siemClient = context.getAppClient(); const exceptionsListClient = context.getExceptionListClient() ?? exceptionsClient; - const ruleAssetsClient = ruleAssetSavedObjectsClientFactory(savedObjectsClient); + const ruleAssetsClient = ruleAssetsClientFactory(savedObjectsClient); const { maxTimelineImportExportSize } = config; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/register_routes.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/register_routes.ts index 39e822af3e147..c396eea87da9d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/register_routes.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/register_routes.ts @@ -5,7 +5,6 @@ * 2.0. */ -import type { ConfigType } from '../../../../config'; import type { SetupPlugins } from '../../../../plugin_contract'; import type { SecuritySolutionPluginRouter } from '../../../../types'; @@ -14,9 +13,8 @@ import { installPrebuiltRulesAndTimelinesRoute } from './install_prebuilt_rules_ export const registerPrebuiltRulesRoutes = ( router: SecuritySolutionPluginRouter, - config: ConfigType, security: SetupPlugins['security'] ) => { - getPrebuiltRulesAndTimelinesStatusRoute(router, config, security); + getPrebuiltRulesAndTimelinesStatusRoute(router, security); installPrebuiltRulesAndTimelinesRoute(router); }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_latest_prebuilt_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_latest_prebuilt_rules.ts index 914ab6b7ccf7f..36fb03c9bac7a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_latest_prebuilt_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_latest_prebuilt_rules.ts @@ -13,32 +13,23 @@ import { PrebuiltRuleToInstall } from '../../../../../common/detection_engine/pr import { withSecuritySpan } from '../../../../utils/with_security_span'; import type { IRuleAssetSOAttributes, - RuleAssetSavedObjectsClient, + IRuleAssetsClient, } from './rule_asset/rule_asset_saved_objects_client'; +import { prebuiltRulesToMap } from './utils'; + export const getLatestPrebuiltRules = async ( - client: RuleAssetSavedObjectsClient + ruleAssetsClient: IRuleAssetsClient ): Promise> => withSecuritySpan('getLatestPrebuiltRules', async () => { - const fleetRules = await getFleetRules(client); - return new Map(fleetRules.map((rule) => [rule.rule_id, rule])); + const ruleAssets = await ruleAssetsClient.fetchLatestVersions(); + return prebuiltRulesToMap(validateRuleAssets(ruleAssets)); }); -/** - * Retrieve and validate prebuilt rules that were installed from Fleet as saved objects. - */ -const getFleetRules = async ( - client: RuleAssetSavedObjectsClient -): Promise => { - const fleetResponse = await client.all(); - const fleetRules = fleetResponse.map((so) => so.attributes); - return validateFleetRules(fleetRules); -}; - /** * Validate the rules from Saved Objects created by Fleet. */ -const validateFleetRules = (rules: IRuleAssetSOAttributes[]): PrebuiltRuleToInstall[] => { +const validateRuleAssets = (rules: IRuleAssetSOAttributes[]): PrebuiltRuleToInstall[] => { return rules.map((rule) => { const decoded = PrebuiltRuleToInstall.decode(rule); const checked = exactCheck(rule, decoded); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_asset/rule_asset_saved_objects_client.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_asset/rule_asset_saved_objects_client.ts index be963fb3dae9e..556ebbe2df108 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_asset/rule_asset_saved_objects_client.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_asset/rule_asset_saved_objects_client.ts @@ -5,17 +5,16 @@ * 2.0. */ -import type { - SavedObjectsClientContract, - SavedObjectsFindOptions, - SavedObjectsFindResponse, -} from '@kbn/core/server'; +import type { AggregationsMultiBucketAggregateBase } from '@elastic/elasticsearch/lib/api/types'; +import type { AggregationsTopHitsAggregate } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { SavedObjectsClientContract } from '@kbn/core/server'; +import { invariant } from '../../../../../../common/utils/invariant'; +import { withSecuritySpan } from '../../../../../utils/with_security_span'; import { ruleAssetSavedObjectType } from './rule_asset_saved_object_mappings'; -const DEFAULT_PAGE_SIZE = 100; +const MAX_PREBUILT_RULES_COUNT = 10_000; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export interface IRuleAssetSOAttributes extends Record { +export interface IRuleAssetSOAttributes extends Record { rule_id: string | null | undefined; version: string | null | undefined; name: string | null | undefined; @@ -27,33 +26,53 @@ export interface IRuleAssetSavedObject { attributes: IRuleAssetSOAttributes; } -export interface RuleAssetSavedObjectsClient { - find: ( - options?: Omit - ) => Promise>; - all: () => Promise; +export interface IRuleAssetsClient { + fetchLatestVersions: () => Promise; } -export const ruleAssetSavedObjectsClientFactory = ( +export const ruleAssetsClientFactory = ( savedObjectsClient: SavedObjectsClientContract -): RuleAssetSavedObjectsClient => { +): IRuleAssetsClient => { return { - find: (options) => - savedObjectsClient.find({ - ...options, - type: ruleAssetSavedObjectType, - }), - all: async () => { - const finder = savedObjectsClient.createPointInTimeFinder({ - perPage: DEFAULT_PAGE_SIZE, - type: ruleAssetSavedObjectType, + fetchLatestVersions: () => { + return withSecuritySpan('RuleAssetsClient.fetchLatestVersions', async () => { + const findResult = await savedObjectsClient.find< + IRuleAssetSavedObject, + { + rules: AggregationsMultiBucketAggregateBase<{ + latest_version: AggregationsTopHitsAggregate; + }>; + } + >({ + type: ruleAssetSavedObjectType, + aggs: { + rules: { + terms: { + field: `${ruleAssetSavedObjectType}.attributes.rule_id`, + size: MAX_PREBUILT_RULES_COUNT, + }, + aggs: { + latest_version: { + top_hits: { + size: 1, + sort: { + [`${ruleAssetSavedObjectType}.version`]: 'desc', + }, + }, + }, + }, + }, + }, + }); + const buckets = findResult.aggregations?.rules?.buckets ?? []; + + invariant(Array.isArray(buckets), 'Expected buckets to be an array'); + + return buckets.map((bucket) => { + const hit = bucket.latest_version.hits.hits[0]; + return hit._source[ruleAssetSavedObjectType]; + }); }); - const responses: IRuleAssetSavedObject[] = []; - for await (const response of finder.find()) { - responses.push(...response.saved_objects.map((so) => so as IRuleAssetSavedObject)); - } - await finder.close(); - return responses; }, }; }; diff --git a/x-pack/plugins/security_solution/server/routes/index.ts b/x-pack/plugins/security_solution/server/routes/index.ts index 38809aff316a0..de0a0c4fab69d 100644 --- a/x-pack/plugins/security_solution/server/routes/index.ts +++ b/x-pack/plugins/security_solution/server/routes/index.ts @@ -91,7 +91,7 @@ export const initRoutes = ( ) => { registerFleetIntegrationsRoutes(router, logger); registerLegacyRuleActionsRoutes(router, logger); - registerPrebuiltRulesRoutes(router, config, security); + registerPrebuiltRulesRoutes(router, security); registerRuleExceptionsRoutes(router); registerManageExceptionsRoutes(router); registerRuleManagementRoutes(router, config, ml, logger); From 7764a7514f0dbd4a0d60c9cef18954e1ee519590 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 17 Jan 2023 12:26:50 -0700 Subject: [PATCH 13/44] [dashboard] remove unnecessary Providers for dashboard actions (#148650) Follow up to https://github.com/elastic/kibana/pull/148037. UiComponent has been remove and Actions no longer break react context. This means that wrapping Action components in Providers is no longer needed. This PR removes these uunnecessary Providers for dashboard actions. Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../filters_notification_action.tsx | 24 ++++++---------- .../library_notification_action.tsx | 28 ++++++------------- 2 files changed, 17 insertions(+), 35 deletions(-) diff --git a/src/plugins/dashboard/public/dashboard_actions/filters_notification_action.tsx b/src/plugins/dashboard/public/dashboard_actions/filters_notification_action.tsx index 247200de71e8f..0847066e166ce 100644 --- a/src/plugins/dashboard/public/dashboard_actions/filters_notification_action.tsx +++ b/src/plugins/dashboard/public/dashboard_actions/filters_notification_action.tsx @@ -10,12 +10,10 @@ import React from 'react'; import { EditPanelAction, isFilterableEmbeddable, ViewMode } from '@kbn/embeddable-plugin/public'; import { type IEmbeddable, isErrorEmbeddable } from '@kbn/embeddable-plugin/public'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; import type { ApplicationStart } from '@kbn/core/public'; import { type AggregateQuery } from '@kbn/es-query'; -import { I18nProvider } from '@kbn/i18n-react'; import { FiltersNotificationPopover } from './filters_notification_popover'; import { dashboardFilterNotificationActionStrings } from './_dashboard_actions_strings'; @@ -60,19 +58,15 @@ export class FiltersNotificationAction implements Action - - - - - - + + + ); }; diff --git a/src/plugins/dashboard/public/dashboard_actions/library_notification_action.tsx b/src/plugins/dashboard/public/dashboard_actions/library_notification_action.tsx index 0d46aa66595ea..8f677450dca15 100644 --- a/src/plugins/dashboard/public/dashboard_actions/library_notification_action.tsx +++ b/src/plugins/dashboard/public/dashboard_actions/library_notification_action.tsx @@ -15,9 +15,7 @@ import { isReferenceOrValueEmbeddable, } from '@kbn/embeddable-plugin/public'; import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; -import { pluginServices } from '../services/plugin_services'; import { UnlinkFromLibraryAction } from './unlink_from_library_action'; import { LibraryNotificationPopover } from './library_notification_popover'; import { dashboardLibraryNotificationStrings } from './_dashboard_actions_strings'; @@ -33,15 +31,7 @@ export class LibraryNotificationAction implements Action { const { embeddable } = context; return ( - - - + ); }; From b345f7563422ad8ac3ce2be6bab079ef13ff81ff Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Tue, 17 Jan 2023 21:04:23 +0100 Subject: [PATCH 14/44] Upgrade Node.js from v16.18.1 to v18.13.0 (#144012) Closes #134930 Breaking changes in Node.js majors: - `17.0.0`: https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V17.md#17.0.0 - `18.0.0`: https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V18.md#18.0.0 --- .buildkite/package-lock.json | 16 +-- .buildkite/package.json | 4 +- .ci/Dockerfile | 2 +- .node-version | 2 +- .nvmrc | 2 +- WORKSPACE.bazel | 12 +- .../advanced/upgrading-nodejs.asciidoc | 4 +- package.json | 14 +-- packages/kbn-i18n/src/core/i18n.test.ts | 8 +- packages/kbn-monaco/BUILD.bazel | 2 + .../src/optimizer/observe_worker.ts | 1 + packages/kbn-ui-shared-deps-npm/BUILD.bazel | 2 + packages/kbn-ui-shared-deps-src/BUILD.bazel | 2 + .../build/tasks/patch_native_modules_task.ts | 36 +++--- ...est_oauth_client_credentials_token.test.ts | 1 + .../lib/request_oauth_jwt_token.test.ts | 1 + .../server/lib/request_oauth_token.test.ts | 1 + .../components/curations_table.test.tsx | 4 +- .../shared/formatted_date_time/index.test.tsx | 2 +- .../server/services/epm/archive/extract.ts | 19 +-- .../server/lib/tasks/execute_report.ts | 23 +++- .../email/send_email_graph_api.test.ts | 3 + .../servicenow_itom/api.test.ts | 2 +- .../connector_types/servicenow_itom/api.ts | 2 +- .../service_api_client.test.ts | 7 +- yarn.lock | 113 ++++++++++++------ 26 files changed, 177 insertions(+), 108 deletions(-) diff --git a/.buildkite/package-lock.json b/.buildkite/package-lock.json index cc303035b972e..d28509d0de482 100644 --- a/.buildkite/package-lock.json +++ b/.buildkite/package-lock.json @@ -16,12 +16,12 @@ "tslib": "*" }, "devDependencies": { - "@types/chai": "^4.2.10", + "@types/chai": "^4.3.3", "@types/js-yaml": "^4.0.5", "@types/minimatch": "^3.0.5", "@types/mocha": "^10.0.1", "@types/node": "^15.12.2", - "chai": "^4.2.0", + "chai": "^4.3.6", "mocha": "^10.2.0", "nock": "^12.0.2", "ts-node": "^10.7.0", @@ -242,9 +242,9 @@ "dev": true }, "node_modules/@types/chai": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", - "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", "dev": true }, "node_modules/@types/js-yaml": { @@ -1847,9 +1847,9 @@ "dev": true }, "@types/chai": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", - "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", "dev": true }, "@types/js-yaml": { diff --git a/.buildkite/package.json b/.buildkite/package.json index 620345b081410..2dbcbc3c0082f 100644 --- a/.buildkite/package.json +++ b/.buildkite/package.json @@ -15,12 +15,12 @@ "tslib": "*" }, "devDependencies": { - "@types/chai": "^4.2.10", + "@types/chai": "^4.3.3", "@types/js-yaml": "^4.0.5", "@types/minimatch": "^3.0.5", "@types/mocha": "^10.0.1", "@types/node": "^15.12.2", - "chai": "^4.2.0", + "chai": "^4.3.6", "mocha": "^10.2.0", "nock": "^12.0.2", "ts-node": "^10.7.0", diff --git a/.ci/Dockerfile b/.ci/Dockerfile index 88966aa5062ac..4f5236c733bc3 100644 --- a/.ci/Dockerfile +++ b/.ci/Dockerfile @@ -1,7 +1,7 @@ # NOTE: This Dockerfile is ONLY used to run certain tasks in CI. It is not used to run Kibana or as a distributable. # If you're looking for the Kibana Docker image distributable, please see: src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts -ARG NODE_VERSION=16.18.1 +ARG NODE_VERSION=18.13.0 FROM node:${NODE_VERSION} AS base diff --git a/.node-version b/.node-version index 5397c87fabfd3..d939939b25962 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -16.18.1 +18.13.0 diff --git a/.nvmrc b/.nvmrc index 5397c87fabfd3..d939939b25962 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16.18.1 +18.13.0 diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index 0a7f9596abdd8..2e0916692591a 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel @@ -22,13 +22,13 @@ load("@build_bazel_rules_nodejs//:index.bzl", "node_repositories", "yarn_install # Setup the Node.js toolchain for the architectures we want to support node_repositories( node_repositories = { - "16.18.1-darwin_amd64": ("node-v16.18.1-darwin-x64.tar.gz", "node-v16.18.1-darwin-x64", "c190e106d4ac6177d1db3a5a739d39dd68bd276ba17f3d3c84039a93717e081e"), - "16.18.1-darwin_arm64": ("node-v16.18.1-darwin-arm64.tar.gz", "node-v16.18.1-darwin-arm64", "71720bb0a80cf158d8fdf492def08048befd953ad45e2458b1d095e32c612ba7"), - "16.18.1-linux_arm64": ("node-v16.18.1-linux-arm64.tar.xz", "node-v16.18.1-linux-arm64", "98d81a2d08f88646541d282b7ccc32429f8706ddcb30943fc3779ef9674ebb93"), - "16.18.1-linux_amd64": ("node-v16.18.1-linux-x64.tar.xz", "node-v16.18.1-linux-x64", "de2c694e7081c37022817d27a65b02f69ecf4c49699d65585e8e24431b7bc920"), - "16.18.1-windows_amd64": ("node-v16.18.1-win-x64.zip", "node-v16.18.1-win-x64", "db6a81de8e8ca3444495f1bcf04a883c076b4325d0fbaa032a190f88b38b30c5"), + "18.13.0-darwin_amd64": ("node-v18.13.0-darwin-x64.tar.gz", "node-v18.13.0-darwin-x64", "8b57c4da4ff6cca19d5ef7953f8816e3406d1508a2e4ee7f997984b3b1d11b77"), + "18.13.0-darwin_arm64": ("node-v18.13.0-darwin-arm64.tar.gz", "node-v18.13.0-darwin-arm64", "418d535e64dbcbd628715180c2de4ffcecb8a84b81f233c60e6ab9f0d795c249"), + "18.13.0-linux_arm64": ("node-v18.13.0-linux-arm64.tar.xz", "node-v18.13.0-linux-arm64", "5b338667822341d1ea3b18d5b37d442a655829b9eafdc5f9008f00b8451ac148"), + "18.13.0-linux_amd64": ("node-v18.13.0-linux-x64.tar.xz", "node-v18.13.0-linux-x64", "7f5d6922a91986ef059ba8a4396aa435440adacfe6fc6fab60a857c8f2cf5e7a"), + "18.13.0-windows_amd64": ("node-v18.13.0-win-x64.zip", "node-v18.13.0-win-x64", "29c99ad1167ddbd72f2b15e91b560e36ac785b1873ba6791ab50d9d62f1957e2"), }, - node_version = "16.18.1", + node_version = "18.13.0", node_urls = [ "https://nodejs.org/dist/v{version}/{filename}", ], diff --git a/docs/developer/advanced/upgrading-nodejs.asciidoc b/docs/developer/advanced/upgrading-nodejs.asciidoc index 348a43c0595ff..16e8502450c17 100644 --- a/docs/developer/advanced/upgrading-nodejs.asciidoc +++ b/docs/developer/advanced/upgrading-nodejs.asciidoc @@ -13,11 +13,11 @@ These files must be updated when upgrading Node.js: If they are not, and the update is urgent, you can skip this file and update it later once Docker Hub has been updated. - {kib-repo}blob/{branch}/.node-version[`.node-version`] - {kib-repo}blob/{branch}/.nvmrc[`.nvmrc`] - - {kib-repo}blob/{branch}/package.json[`package.json`] - The version is specified in the `engines.node` field. + - {kib-repo}blob/{branch}/package.json[`package.json`] - The version is specified in the `engines.node` field (if possible, also upgrade `@types/node` to match the new version, both under `devDependencies` and `resolutions`). - {kib-repo}blob/{branch}/WORKSPACE.bazel[`WORKSPACE.bazel`] - The version is specified in the `node_version` property. Besides this property, the list of files under `node_repositories` must be updated along with their respective SHA256 hashes. These can be found on the https://nodejs.org[nodejs.org] website. - Example for Node.js v16.18.1: https://nodejs.org/dist/v16.18.1/SHASUMS256.txt.asc + Example for Node.js v18.13.0: https://nodejs.org/dist/v18.13.0/SHASUMS256.txt.asc See PR {kib-repo}pull/128123[#128123] for an example of how the Node.js version has been upgraded previously. diff --git a/package.json b/package.json index 3191e25901a51..98171db69f469 100644 --- a/package.json +++ b/package.json @@ -68,11 +68,11 @@ "url": "https://github.com/elastic/kibana.git" }, "engines": { - "node": "16.18.1", + "node": "18.13.0", "yarn": "^1.22.19" }, "resolutions": { - "**/@types/node": "16.11.41", + "**/@types/node": "18.11.18", "**/chokidar": "^3.5.3", "**/deepmerge": "^4.2.2", "**/fast-deep-equal": "^3.1.1", @@ -622,7 +622,7 @@ "query-string": "^6.13.2", "rbush": "^3.0.1", "re-resizable": "^6.1.1", - "re2": "1.17.4", + "re2": "1.17.7", "react": "^17.0.2", "react-ace": "^7.0.5", "react-beautiful-dnd": "^13.1.0", @@ -683,7 +683,7 @@ "styled-components": "^5.1.0", "suricata-sid-db": "^1.0.2", "symbol-observable": "^1.2.0", - "tar": "^6.1.11", + "tar": "^6.1.13", "tinycolor2": "1.4.1", "tinygradient": "0.4.3", "ts-easing": "^0.2.0", @@ -936,7 +936,7 @@ "@types/multistream": "^4.1.0", "@types/mustache": "^0.8.31", "@types/nock": "^10.0.3", - "@types/node": "16.11.41", + "@types/node": "18.11.18", "@types/node-fetch": "^2.6.0", "@types/node-forge": "^1.3.1", "@types/nodemailer": "^6.4.0", @@ -983,7 +983,7 @@ "@types/styled-components": "^5.1.0", "@types/supertest": "^2.0.5", "@types/tapable": "^1.0.6", - "@types/tar": "^4.0.5", + "@types/tar": "^6.1.3", "@types/tempy": "^0.2.0", "@types/testing-library__jest-dom": "^5.14.5", "@types/tinycolor2": "^1.4.1", @@ -1158,7 +1158,7 @@ "simple-git": "^3.15.1", "sinon": "^7.4.2", "sort-package-json": "^1.53.1", - "source-map": "^0.7.3", + "source-map": "^0.7.4", "string-replace-loader": "^2.2.0", "style-loader": "^1.1.3", "stylelint": "^14.9.1", diff --git a/packages/kbn-i18n/src/core/i18n.test.ts b/packages/kbn-i18n/src/core/i18n.test.ts index dfea790f129b5..f9a6535d881ee 100644 --- a/packages/kbn-i18n/src/core/i18n.test.ts +++ b/packages/kbn-i18n/src/core/i18n.test.ts @@ -662,13 +662,13 @@ describe('I18n engine', () => { i18n.translate('a.short', { values: { expires: new Date(2018, 5, 20, 18, 40, 30, 50) }, } as any) - ).toBe('Coupon expires at 6:40 PM'); + ).toBe('Coupon expires at 6:40 PM'); expect( i18n.translate('a.medium', { values: { expires: new Date(2018, 5, 20, 18, 40, 30, 50) }, } as any) - ).toBe('Coupon expires at 6:40:30 PM'); + ).toBe('Coupon expires at 6:40:30 PM'); }); test('should format default messages with time formatter', () => { @@ -679,14 +679,14 @@ describe('I18n engine', () => { defaultMessage: 'Coupon expires at {expires, time, short}', values: { expires: new Date(2018, 5, 20, 18, 40, 30, 50) }, }) - ).toBe('Coupon expires at 6:40 PM'); + ).toBe('Coupon expires at 6:40 PM'); expect( i18n.translate('foo', { defaultMessage: 'Coupon expires at {expires, time, medium}', values: { expires: new Date(2018, 5, 20, 18, 40, 30, 50) }, }) - ).toBe('Coupon expires at 6:40:30 PM'); + ).toBe('Coupon expires at 6:40:30 PM'); }); test('should format message with a custom format', () => { diff --git a/packages/kbn-monaco/BUILD.bazel b/packages/kbn-monaco/BUILD.bazel index 8d13702e74588..2ca10b073fd18 100644 --- a/packages/kbn-monaco/BUILD.bazel +++ b/packages/kbn-monaco/BUILD.bazel @@ -56,9 +56,11 @@ webpack_cli( env = select({ "//:dist": { "NODE_ENV": "production", + "NODE_OPTIONS": "--openssl-legacy-provider", }, "//conditions:default": { "NODE_ENV": "development", + "NODE_OPTIONS": "--openssl-legacy-provider", }, }), visibility = ["//visibility:public"], diff --git a/packages/kbn-optimizer/src/optimizer/observe_worker.ts b/packages/kbn-optimizer/src/optimizer/observe_worker.ts index cf250a7deef6e..49c150fbf2dcb 100644 --- a/packages/kbn-optimizer/src/optimizer/observe_worker.ts +++ b/packages/kbn-optimizer/src/optimizer/observe_worker.ts @@ -60,6 +60,7 @@ function usingWorkerProc(config: OptimizerConfig, fn: (proc: ChildProcess) => (): ProcResource => { const proc = fork(require.resolve('../worker/run_worker'), [], { execArgv: [ + '--openssl-legacy-provider', `--require=@kbn/babel-register/install`, ...(inspectFlag && config.inspectWorkers ? [`${inspectFlag}=${inspectPortCounter++}`] diff --git a/packages/kbn-ui-shared-deps-npm/BUILD.bazel b/packages/kbn-ui-shared-deps-npm/BUILD.bazel index 2b49f1e5a92f1..a45f183ff80ef 100644 --- a/packages/kbn-ui-shared-deps-npm/BUILD.bazel +++ b/packages/kbn-ui-shared-deps-npm/BUILD.bazel @@ -83,9 +83,11 @@ webpack_cli( env = select({ "//:dist": { "NODE_ENV": "production", + "NODE_OPTIONS": "--openssl-legacy-provider", }, "//conditions:default": { "NODE_ENV": "development", + "NODE_OPTIONS": "--openssl-legacy-provider", }, }) ) diff --git a/packages/kbn-ui-shared-deps-src/BUILD.bazel b/packages/kbn-ui-shared-deps-src/BUILD.bazel index 0b350c51331ff..49c2cc62dcfe5 100644 --- a/packages/kbn-ui-shared-deps-src/BUILD.bazel +++ b/packages/kbn-ui-shared-deps-src/BUILD.bazel @@ -45,9 +45,11 @@ webpack_cli( env = select({ "//:dist": { "NODE_ENV": "production", + "NODE_OPTIONS": "--openssl-legacy-provider", }, "//conditions:default": { "NODE_ENV": "development", + "NODE_OPTIONS": "--openssl-legacy-provider", }, }), visibility = ["//visibility:public"], diff --git a/src/dev/build/tasks/patch_native_modules_task.ts b/src/dev/build/tasks/patch_native_modules_task.ts index 1c1bebfa86c0e..596b94933385e 100644 --- a/src/dev/build/tasks/patch_native_modules_task.ts +++ b/src/dev/build/tasks/patch_native_modules_task.ts @@ -41,50 +41,50 @@ interface Package { const packages: Package[] = [ { name: 're2', - version: '1.17.4', + version: '1.17.7', destinationPath: 'node_modules/re2/build/Release/re2.node', extractMethod: 'gunzip', archives: { 'darwin-x64': { - url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.4/darwin-x64-93.gz', - sha256: '9558c5cb39622e9b3653203e772b129d6c634e7dbd7af1b244352fc1d704601f', + url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.7/darwin-x64-108.gz', + sha256: '4ed378c5a7fe6134b717afe7642254aff1ed7a881cbcaa53a012ac3efab49f99', }, 'linux-x64': { - url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.4/linux-x64-93.gz', - sha256: '4d06747b266c75b6f7ced93977692c0586ce6a52924cabb569bd966378941aa1', + url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.7/linux-x64-108.gz', + sha256: '197a617ca2965f220848561afed71ff6df653f6d79910cf38e866c84ab38a236', }, // ARM builds are currently done manually as Github Actions used in upstream project // do not natively support an ARM target. - // From a AWS Graviton instance running Ubuntu: - // * install build-essential package + // From an AWS Graviton instance running Ubuntu or a GCE T2A instance running Debian: + // * install build-essential package: `sudo apt-get update` + `sudo apt install build-essential` // * install nvm and the node version used by the Kibana repository - // * `npm install re2@1.17.4` + // * `npm install re2@1.17.7` // * re2 will build itself on install - // * `cp node_modules/re2/build/Release/re2.node > linux-arm64-$(node -e "console.log(process.versions.modules)") + // * `cp node_modules/re2/build/Release/re2.node linux-arm64-$(node -e "console.log(process.versions.modules)")` // * `gzip linux-arm64-*` // * capture the sha256 with: `shasum -a 256 linux-arm64-*` - // * upload the `linux-arm64-*.gz` artifact to the `yarn-prebuilt-assets` bucket in GCS using the correct version number + // * upload the `linux-arm64-*.gz` artifact to the `yarn-prebuilt-artifacts` bucket in GCS using the correct version number 'linux-arm64': { - url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.4/linux-arm64-93.gz', - sha256: '25409584f76f3d6ed85463d84adf094eb6e256ed1cb0b754b95bcbda6691fc26', + url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.7/linux-arm64-108.gz', + sha256: 'a690087a1a1fd9887aac1abdab68d1992600e218be10783da6d3381cca950c1a', }, // A similar process is necessary for building on ARM macs: // * bootstrap and re2 will build itself on install - // * `cp node_modules/re2/build/Release/re2.node > darwin-arm64-$(node -e "console.log(process.versions.modules)") + // * `cp node_modules/re2/build/Release/re2.node darwin-arm64-$(node -e "console.log(process.versions.modules)")` // * `gzip darwin-arm64-*` // * capture the sha256 with: `shasum -a 256 darwin-arm64-*` - // * upload the `darwin-arm64-*.gz` artifact to the `yarn-prebuilt-assets` bucket in GCS using the correct version number + // * upload the `darwin-arm64-*.gz` artifact to the `yarn-prebuilt-artifacts` bucket in GCS using the correct version number 'darwin-arm64': { - url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.4/darwin-arm64-93.gz', - sha256: 'd4b708749ddef1c87019f6b80e051ed0c29ccd1de34f233c47d8dcaddf803872', + url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.7/darwin-arm64-108.gz', + sha256: '42afc32137ff5c5bebae5d68347a9786906748c2f28e06194d8950707f2ae90e', }, 'win32-x64': { - url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.4/win32-x64-93.gz', - sha256: '0320d0c0385432944c6fb3c8c8fcd78d440ce5626f7618f9ec71d88e44820674', + url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.7/win32-x64-108.gz', + sha256: 'ff72fe02de652262659c8e17e44a932f3c873362233756b40d1a97538d05de92', }, }, }, diff --git a/x-pack/plugins/actions/server/lib/request_oauth_client_credentials_token.test.ts b/x-pack/plugins/actions/server/lib/request_oauth_client_credentials_token.test.ts index 20896e2691f10..223c8c28b55bc 100644 --- a/x-pack/plugins/actions/server/lib/request_oauth_client_credentials_token.test.ts +++ b/x-pack/plugins/actions/server/lib/request_oauth_client_credentials_token.test.ts @@ -74,6 +74,7 @@ describe('requestOAuthClientCredentialsToken', () => { "maxSockets": Infinity, "maxTotalSockets": Infinity, "options": Object { + "noDelay": true, "path": null, "rejectUnauthorized": true, }, diff --git a/x-pack/plugins/actions/server/lib/request_oauth_jwt_token.test.ts b/x-pack/plugins/actions/server/lib/request_oauth_jwt_token.test.ts index 318775762bbbd..af65bcf67d3db 100644 --- a/x-pack/plugins/actions/server/lib/request_oauth_jwt_token.test.ts +++ b/x-pack/plugins/actions/server/lib/request_oauth_jwt_token.test.ts @@ -75,6 +75,7 @@ describe('requestOAuthJWTToken', () => { "maxSockets": Infinity, "maxTotalSockets": Infinity, "options": Object { + "noDelay": true, "path": null, "rejectUnauthorized": true, }, diff --git a/x-pack/plugins/actions/server/lib/request_oauth_token.test.ts b/x-pack/plugins/actions/server/lib/request_oauth_token.test.ts index cc9ea6a74517a..9843783aadf8d 100644 --- a/x-pack/plugins/actions/server/lib/request_oauth_token.test.ts +++ b/x-pack/plugins/actions/server/lib/request_oauth_token.test.ts @@ -82,6 +82,7 @@ describe('requestOAuthToken', () => { "maxSockets": Infinity, "maxTotalSockets": Infinity, "options": Object { + "noDelay": true, "path": null, "rejectUnauthorized": true, }, diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/curations_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/curations_table.test.tsx index d86cb8592635a..3d98b684f8dfc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/curations_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/curations_table.test.tsx @@ -84,8 +84,8 @@ describe('CurationsTable', () => { expect(tableContent).toContain('mountains, valleys'); expect(tableContent).toContain('Last updated'); - expect(tableContent).toContain('Jan 1, 1970 12:00 PM'); - expect(tableContent).toContain('Jan 2, 1970 12:00 PM'); + expect(tableContent).toContain('Jan 1, 1970 12:00 PM'); + expect(tableContent).toContain('Jan 2, 1970 12:00 PM'); }); it('renders queries with curation links and curation suggestion badges', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/formatted_date_time/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/formatted_date_time/index.test.tsx index f74125b1528c7..fd76943d3e727 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/formatted_date_time/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/formatted_date_time/index.test.tsx @@ -16,7 +16,7 @@ describe('FormattedDateTime', () => { const date = new Date('1970-01-01T12:00:00'); const wrapper = mountWithIntl(); - expect(wrapper.text()).toEqual('Jan 1, 1970 12:00 PM'); + expect(wrapper.text()).toEqual('Jan 1, 1970 12:00 PM'); }); it('does not render time if hideTime is passed', () => { diff --git a/x-pack/plugins/fleet/server/services/epm/archive/extract.ts b/x-pack/plugins/fleet/server/services/epm/archive/extract.ts index 03caf8901f40b..84c2457f4dafe 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/extract.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/extract.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { finished } from 'stream/promises'; + import tar from 'tar'; import yauzl from 'yauzl'; @@ -16,19 +18,20 @@ export async function untarBuffer( buffer: Buffer, filter = (entry: ArchiveEntry): boolean => true, onEntry = (entry: ArchiveEntry): void => {} -): Promise { +) { const deflatedStream = bufferToStream(buffer); // use tar.list vs .extract to avoid writing to disk - const inflateStream = tar.list().on('entry', (entry: tar.FileStat) => { - const path = entry.header.path || ''; + const inflateStream = tar.list().on('entry', (entry) => { + const path = entry.path || ''; if (!filter({ path })) return; - streamToBuffer(entry).then((entryBuffer) => onEntry({ buffer: entryBuffer, path })); + streamToBuffer(entry as unknown as NodeJS.ReadableStream).then((entryBuffer) => + onEntry({ buffer: entryBuffer, path }) + ); }); - return new Promise((resolve, reject) => { - inflateStream.on('end', resolve).on('error', reject); - deflatedStream.pipe(inflateStream); - }); + deflatedStream.pipe(inflateStream); + + await finished(inflateStream); } export async function unzipBuffer( diff --git a/x-pack/plugins/reporting/server/lib/tasks/execute_report.ts b/x-pack/plugins/reporting/server/lib/tasks/execute_report.ts index ca3ba4445f940..abebdef58fe33 100644 --- a/x-pack/plugins/reporting/server/lib/tasks/execute_report.ts +++ b/x-pack/plugins/reporting/server/lib/tasks/execute_report.ts @@ -10,8 +10,9 @@ import type { Logger } from '@kbn/core/server'; import moment from 'moment'; import * as Rx from 'rxjs'; import { timeout } from 'rxjs/operators'; -import { finished, Writable } from 'stream'; -import { promisify } from 'util'; +import { Writable } from 'stream'; +import { finished } from 'stream/promises'; +import { setTimeout } from 'timers/promises'; import type { RunContext, TaskManagerStartContract, @@ -59,6 +60,22 @@ function reportFromTask(task: ReportTaskParams) { return new Report({ ...task, _id: task.id, _index: task.index }); } +async function finishedWithNoPendingCallbacks(stream: Writable) { + await finished(stream, { readable: false }); + + // Race condition workaround: + // `finished(...)` will resolve while there's still pending callbacks in the writable part of the `stream`. + // This introduces a race condition where the code continues before the writable part has completely finished. + // The `pendingCallbacks` function is a hack to ensure that all pending callbacks have been called before continuing. + // For more information, see: https://github.com/nodejs/node/issues/46170 + await (async function pendingCallbacks(delay = 1) { + if ((stream as any)._writableState.pendingcb > 0) { + await setTimeout(delay); + await pendingCallbacks(delay < 32 ? delay * 2 : delay); + } + })(); +} + export class ExecuteReportTask implements ReportingTask { public TYPE = REPORTING_EXECUTE_TYPE; @@ -377,7 +394,7 @@ export class ExecuteReportTask implements ReportingTask { stream.end(); - await promisify(finished)(stream, { readable: false }); + await finishedWithNoPendingCallbacks(stream); report._seq_no = stream.getSeqNo()!; report._primary_term = stream.getPrimaryTerm()!; diff --git a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts index 4ab03837f416b..199681a13e968 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts @@ -90,6 +90,7 @@ describe('sendEmailGraphApi', () => { "maxSockets": Infinity, "maxTotalSockets": Infinity, "options": Object { + "noDelay": true, "path": null, "rejectUnauthorized": true, }, @@ -180,6 +181,7 @@ describe('sendEmailGraphApi', () => { "maxSockets": Infinity, "maxTotalSockets": Infinity, "options": Object { + "noDelay": true, "path": null, "rejectUnauthorized": true, }, @@ -269,6 +271,7 @@ describe('sendEmailGraphApi', () => { "maxSockets": Infinity, "maxTotalSockets": Infinity, "options": Object { + "noDelay": true, "path": null, "rejectUnauthorized": true, }, diff --git a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.test.ts index 3731aa6f09dc7..584a06f4b407a 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.test.ts @@ -15,7 +15,7 @@ describe('api_itom', () => { let externalService: jest.Mocked; const eventParamsWithFormattedDate = { ...itomEventParams, - time_of_event: '2021-10-13, 10:51:44', + time_of_event: '2021-10-13 10:51:44', }; beforeEach(() => { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.ts b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.ts index d9479792967b2..c68f1d4419eb1 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.ts @@ -20,7 +20,7 @@ const formatTimeOfEvent = (timeOfEvent: string | null): string | undefined => { return isValidDate(date) ? // The format is: yyyy-MM-dd HH:mm:ss GMT - date.toLocaleDateString('en-CA', { + date.toLocaleDateString('eo', { year: 'numeric', month: '2-digit', day: '2-digit', diff --git a/x-pack/plugins/synthetics/server/synthetics_service/service_api_client.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/service_api_client.test.ts index 62a54db4460a6..52056b77ae8b7 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/service_api_client.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/service_api_client.test.ts @@ -200,7 +200,7 @@ describe('callAPI', () => { 'x-kibana-version': '8.7.0', }, httpsAgent: expect.objectContaining({ - options: { rejectUnauthorized: true, path: null }, + options: { noDelay: true, rejectUnauthorized: true, path: null }, }), method: 'POST', url: 'https://service.dev/monitors', @@ -213,7 +213,7 @@ describe('callAPI', () => { 'x-kibana-version': '8.7.0', }, httpsAgent: expect.objectContaining({ - options: { rejectUnauthorized: true, path: null }, + options: { noDelay: true, rejectUnauthorized: true, path: null }, }), method: 'POST', url: 'https://qa.service.elstc.co/monitors', @@ -226,7 +226,7 @@ describe('callAPI', () => { 'x-kibana-version': '8.7.0', }, httpsAgent: expect.objectContaining({ - options: { rejectUnauthorized: true, path: null }, + options: { noDelay: true, rejectUnauthorized: true, path: null }, }), method: 'POST', url: 'https://qa.service.stg.co/monitors', @@ -293,6 +293,7 @@ describe('callAPI', () => { httpsAgent: expect.objectContaining({ options: { rejectUnauthorized: true, + noDelay: true, path: null, cert: 'test-certificate', key: 'test-key', diff --git a/yarn.lock b/yarn.lock index 7fe3223f3b860..8133cfeb06aa2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7348,13 +7348,6 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== -"@types/minipass@*": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@types/minipass/-/minipass-2.2.0.tgz#51ad404e8eb1fa961f75ec61205796807b6f9651" - integrity sha512-wuzZksN4w4kyfoOv/dlpov4NOunwutLA/q7uc00xU02ZyUY+aoM5PWIXEKBMnm0NHd4a+N71BMjq+x7+2Af1fg== - dependencies: - "@types/node" "*" - "@types/mock-fs@^4.13.1": version "4.13.1" resolved "https://registry.yarnpkg.com/@types/mock-fs/-/mock-fs-4.13.1.tgz#9201554ceb23671badbfa8ac3f1fa9e0706305be" @@ -7410,10 +7403,10 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@16.11.41", "@types/node@>= 8", "@types/node@>=12.12.47", "@types/node@>=13.7.0", "@types/node@>=8.9.0", "@types/node@^10.1.0", "@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0", "@types/node@^14.14.31": - version "16.11.41" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.41.tgz#88eb485b1bfdb4c224d878b7832239536aa2f813" - integrity sha512-mqoYK2TnVjdkGk8qXAVGc/x9nSaTpSrFaGFm43BUH3IdoBV0nta6hYaGmdOvIMlbHJbUEVen3gvwpwovAZKNdQ== +"@types/node@*", "@types/node@18.11.18", "@types/node@>= 8", "@types/node@>=12.12.47", "@types/node@>=13.7.0", "@types/node@>=8.9.0", "@types/node@^10.1.0", "@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0", "@types/node@^14.14.31": + version "18.11.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f" + integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA== "@types/nodemailer@^6.4.0": version "6.4.0" @@ -7898,13 +7891,13 @@ resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74" integrity sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA== -"@types/tar@^4.0.5": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@types/tar/-/tar-4.0.5.tgz#5f953f183e36a15c6ce3f336568f6051b7b183f3" - integrity sha512-cgwPhNEabHaZcYIy5xeMtux2EmYBitfqEceBUi2t5+ETy4dW6kswt6WX4+HqLeiiKOo42EXbGiDmVJ2x+vi37Q== +"@types/tar@^6.1.3": + version "6.1.3" + resolved "https://registry.yarnpkg.com/@types/tar/-/tar-6.1.3.tgz#46a2ce7617950c4852dfd7e9cd41aa8161b9d750" + integrity sha512-YzDOr5kdAeqS8dcO6NTTHTMJ44MUCBDoLEIyPtwEn7PssKqUYL49R1iCVJPeiPzPlKi6DbH33eZkpeJ27e4vHg== dependencies: - "@types/minipass" "*" "@types/node" "*" + minipass "^3.3.5" "@types/tempy@^0.2.0": version "0.2.0" @@ -8618,7 +8611,7 @@ abab@^2.0.3, abab@^2.0.4, abab@^2.0.5, abab@^2.0.6: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== -abbrev@1: +abbrev@1, abbrev@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== @@ -16507,10 +16500,10 @@ inquirer@^8.2.3: through "^2.3.6" wrap-ansi "^7.0.0" -install-artifact-from-github@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/install-artifact-from-github/-/install-artifact-from-github-1.3.0.tgz#cab6ff821976b8a35b0c079da19a727c90381a40" - integrity sha512-iT8v1GwOAX0pPXifF/5ihnMhHOCo3OeK7z3TQa4CtSNCIg8k0UxqBEk9jRwz8OP68hHXvJ2gxRa89KYHtBkqGA== +install-artifact-from-github@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/install-artifact-from-github/-/install-artifact-from-github-1.3.1.tgz#eefaad9af35d632e5d912ad1569c1de38c3c2462" + integrity sha512-3l3Bymg2eKDsN5wQuMfgGEj2x6l5MCAv0zPL6rxHESufFVlEAKW/6oY9F1aGgvY/EgWm5+eWGRjINveL4X7Hgg== internal-slot@^1.0.3: version "1.0.3" @@ -19266,7 +19259,7 @@ make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -make-fetch-happen@^10.0.4: +make-fetch-happen@^10.0.3, make-fetch-happen@^10.0.4: version "10.2.1" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== @@ -19968,10 +19961,17 @@ minipass-sized@^1.0.3: dependencies: minipass "^3.0.0" -minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3, minipass@^3.1.6: - version "3.3.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.4.tgz#ca99f95dd77c43c7a76bf51e6d200025eee0ffae" - integrity sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw== +minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3, minipass@^3.1.6, minipass@^3.3.5: + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + +minipass@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.0.0.tgz#7cebb0f9fa7d56f0c5b17853cbe28838a8dbbd3b" + integrity sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw== dependencies: yallist "^4.0.0" @@ -20284,7 +20284,7 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nan@^2.15.0, nan@^2.17.0: +nan@^2.16.0, nan@^2.17.0: version "2.17.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== @@ -20541,6 +20541,22 @@ node-gyp@^8.4.1: tar "^6.1.2" which "^2.0.2" +node-gyp@^9.0.0: + version "9.3.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.3.0.tgz#f8eefe77f0ad8edb3b3b898409b53e697642b319" + integrity sha512-A6rJWfXFz7TQNjpldJ915WFb1LnhO4lIve3ANPbWreuEoLoKlFT3sxIepPBkLhM27crW8YmN+pjlgbasH6cH/Q== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^10.0.3" + nopt "^6.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -20642,6 +20658,13 @@ nopt@^5.0.0: dependencies: abbrev "1" +nopt@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" + integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== + dependencies: + abbrev "^1.0.0" + normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -22795,14 +22818,14 @@ re-resizable@^6.1.1: dependencies: fast-memoize "^2.5.1" -re2@1.17.4: - version "1.17.4" - resolved "https://registry.yarnpkg.com/re2/-/re2-1.17.4.tgz#7bf29290bdde963014e77bd2c2e799a6d788386e" - integrity sha512-xyZ4h5PqE8I9tAxTh3G0UttcK5ufrcUxReFjGzfX61vtanNbS1XZHjnwRSyPcLgChI4KLxVgOT/ioZXnUAdoTA== +re2@1.17.7: + version "1.17.7" + resolved "https://registry.yarnpkg.com/re2/-/re2-1.17.7.tgz#e14cab85a177a5534c7215c322d1b043c55aa1e9" + integrity sha512-X8GSuiBoVWwcjuppqSjsIkRxNUKDdjhkO9SBekQbZ2ksqWUReCy7DQPWOVpoTnpdtdz5PIpTTxTFzvJv5UMfjA== dependencies: - install-artifact-from-github "^1.3.0" - nan "^2.15.0" - node-gyp "^8.4.1" + install-artifact-from-github "^1.3.1" + nan "^2.16.0" + node-gyp "^9.0.0" react-ace@^7.0.5: version "7.0.5" @@ -25115,10 +25138,10 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== +source-map@^0.7.3, source-map@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== source-map@^0.8.0-beta.0: version "0.8.0-beta.0" @@ -26049,7 +26072,7 @@ tar-stream@^2.1.4, tar-stream@^2.2.0: inherits "^2.0.3" readable-stream "^3.1.1" -tar@6.1.11, tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: +tar@6.1.11: version "6.1.11" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== @@ -26061,6 +26084,18 @@ tar@6.1.11, tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: mkdirp "^1.0.3" yallist "^4.0.0" +tar@^6.0.2, tar@^6.1.11, tar@^6.1.13, tar@^6.1.2: + version "6.1.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b" + integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^4.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + tcomb-validation@^3.3.0: version "3.4.1" resolved "https://registry.yarnpkg.com/tcomb-validation/-/tcomb-validation-3.4.1.tgz#a7696ec176ce56a081d9e019f8b732a5a8894b65" From 92418a6362cc78bf5975e9eedde863a21def4b18 Mon Sep 17 00:00:00 2001 From: Jonathan Buttner <56361221+jonathan-buttner@users.noreply.github.com> Date: Tue, 17 Jan 2023 15:21:36 -0500 Subject: [PATCH 15/44] [Cases] API to return a case's connectors information (#147295) This PR implements a new internal API to return the information relating to all the connectors used throughout a case's lifespan. Fixes: https://github.com/elastic/kibana/issues/134346 ``` GET http://localhost:5601/internal/cases//_connectors Response { "my-jira": { "name": "preconfigured-jira", "type": ".jira", "fields": { "issueType": "10001", "parent": null, "priority": null }, "id": "my-jira", "needsToBePushed": true, "hasBeenPushed": false } } ```
    cURL example ``` curl --location --request GET 'http://localhost:5601/internal/cases/ae038370-91d9-11ed-97ce-c35961718f7b/_connectors' \ --header 'kbn-xsrf: hello' \ --header 'Authorization: Basic ' \ --data-raw '' ``` Response ``` { "my-jira": { "name": "preconfigured-jira", "type": ".jira", "fields": { "issueType": "10001", "parent": null, "priority": null }, "id": "my-jira", "needsToBePushed": true, "hasBeenPushed": false } } ```
    Notable changes: - Refactored the user actions service to move the functions that create user actions (builders etc) to its own class `UserActionPersister` - Refactored the `CaseUserActionService` class to pull the saved object client, logger, and other fields passed to each function via parameters to be wrapped in a `context` member field within the class - Plumbed in `savedObjectsService.createSerializer` to transform a raw elasticsearch document into the saved object representation - Added new internal `_connectors` route and `getConnectors` client function - Refactored the integration tests by extracting the connector related utility functions into their own file ## Needs to be pushed algorithm To determine whether a case needs to be pushed for a certain connector we follow this algorithm: - Get all unique connectors - For each connector - Find the most recent user action contain the connector's fields, this will be in the most recent `connector` user action or if the connector was configured only once when the case was initially created it'll be on the `create_case` user action - Grab the most recent push user action if it exists - For each push search for the connector fields that were used in that push - Get the most recent user action that would cause a push to occur (title, description, tags, or comment change) - For each connector - If a push does not exist, we need to push - If a push exists but the fields do not match the field of the most recent connector fields, we need to push because the fields changed - If the timestamp of the most recent user action is more recent than that of the last push (aka the user changed something since we last pushed) we need to push Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../aggregations/aggs_types/bucket_aggs.ts | 32 +- .../cases/common/api/connectors/index.ts | 11 + x-pack/plugins/cases/common/constants.ts | 1 + .../__snapshots__/audit_logger.test.ts.snap | 84 ++ .../cases/server/authorization/index.ts | 8 + .../cases/server/authorization/types.ts | 1 + .../cases/server/client/attachments/delete.ts | 4 +- .../cases/server/client/cases/create.ts | 2 +- .../cases/server/client/cases/delete.ts | 2 +- .../plugins/cases/server/client/cases/push.ts | 4 +- .../cases/server/client/cases/update.ts | 2 +- x-pack/plugins/cases/server/client/factory.ts | 7 + x-pack/plugins/cases/server/client/mocks.ts | 1 + .../server/client/user_actions/client.ts | 20 +- .../server/client/user_actions/connectors.ts | 265 ++++++ .../cases/server/client/user_actions/get.ts | 2 +- .../cases/server/client/user_actions/types.ts | 18 + .../common/models/case_with_comments.ts | 6 +- .../server/routes/api/get_internal_routes.ts | 2 + .../routes/api/internal/get_connectors.ts | 37 + x-pack/plugins/cases/server/services/mocks.ts | 21 +- .../services/user_actions/index.test.ts | 50 +- .../server/services/user_actions/index.ts | 835 +++++++++--------- .../user_actions/operations/create.ts | 433 +++++++++ .../server/services/user_actions/types.ts | 31 +- x-pack/plugins/cases/tsconfig.json | 1 + .../common/lib/connectors.ts | 324 +++++++ .../cases_api_integration/common/lib/utils.ts | 273 +----- .../tests/basic/cases/push_case.ts | 4 +- .../tests/basic/configure/get_connectors.ts | 2 +- .../tests/no_public_base_url/push.ts | 6 +- .../tests/trial/cases/push_case.ts | 12 +- .../user_actions/get_all_user_actions.ts | 6 +- .../tests/trial/configure/get_configure.ts | 8 +- .../tests/trial/configure/get_connectors.ts | 4 +- .../tests/trial/configure/patch_configure.ts | 4 +- .../tests/trial/configure/post_configure.ts | 6 +- .../security_and_spaces/tests/trial/index.ts | 1 + .../tests/trial/internal/get_connectors.ts | 676 ++++++++++++++ .../tests/trial/cases/push_case.ts | 7 +- .../tests/trial/configure/get_configure.ts | 8 +- .../tests/trial/configure/get_connectors.ts | 15 +- .../tests/trial/configure/patch_configure.ts | 8 +- .../tests/trial/configure/post_configure.ts | 8 +- 44 files changed, 2481 insertions(+), 771 deletions(-) create mode 100644 x-pack/plugins/cases/server/client/user_actions/connectors.ts create mode 100644 x-pack/plugins/cases/server/client/user_actions/types.ts create mode 100644 x-pack/plugins/cases/server/routes/api/internal/get_connectors.ts create mode 100644 x-pack/plugins/cases/server/services/user_actions/operations/create.ts create mode 100644 x-pack/test/cases_api_integration/common/lib/connectors.ts create mode 100644 x-pack/test/cases_api_integration/security_and_spaces/tests/trial/internal/get_connectors.ts diff --git a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/aggregations/aggs_types/bucket_aggs.ts b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/aggregations/aggs_types/bucket_aggs.ts index 7a6d94c31f291..20ebeb234b479 100644 --- a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/aggregations/aggs_types/bucket_aggs.ts +++ b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/aggregations/aggs_types/bucket_aggs.ts @@ -61,6 +61,36 @@ const existsSchema = s.object({ }) ), }); + +const rangeSchema = s.object({ + range: s.recordOf( + s.string(), + s.object({ + lt: s.maybe(s.string()), + lte: s.maybe(s.string()), + gt: s.maybe(s.string()), + gte: s.maybe(s.string()), + }) + ), +}); + +const termValueSchema = s.object({ + term: s.recordOf(s.string(), s.object({ value: s.string() })), +}); + +const nestedSchema = s.object({ + nested: s.object({ + path: s.string(), + query: s.object({ + bool: s.object({ + filter: s.arrayOf(termValueSchema), + }), + }), + }), +}); + +const arraySchema = s.arrayOf(s.oneOf([nestedSchema, rangeSchema])); + // TODO: it would be great if we could recursively build the schema since the aggregation have be nested // For more details see how the types are defined in the elasticsearch javascript client: // https://github.com/elastic/elasticsearch-js/blob/4ad5daeaf401ce8ebb28b940075e0a67e56ff9ce/src/api/typesWithBodyKey.ts#L5295 @@ -70,7 +100,7 @@ const boolSchema = s.object({ must_not: s.oneOf([termSchema, existsSchema]), }), s.object({ - filter: s.oneOf([termSchema, existsSchema]), + filter: s.oneOf([termSchema, existsSchema, arraySchema]), }), ]), }); diff --git a/x-pack/plugins/cases/common/api/connectors/index.ts b/x-pack/plugins/cases/common/api/connectors/index.ts index 5f73f3ae493ac..8aac471c634b8 100644 --- a/x-pack/plugins/cases/common/api/connectors/index.ts +++ b/x-pack/plugins/cases/common/api/connectors/index.ts @@ -116,6 +116,15 @@ export const CaseConnectorRt = rt.intersection([ CaseUserActionConnectorRt, ]); +export const GetCaseConnectorsResponseRt = rt.record( + rt.string, + rt.intersection([ + rt.type({ needsToBePushed: rt.boolean, hasBeenPushed: rt.boolean }), + rt.partial(rt.type({ latestPushDate: rt.string }).props), + CaseConnectorRt, + ]) +); + export type CaseUserActionConnector = rt.TypeOf; export type CaseConnector = rt.TypeOf; export type ConnectorTypeFields = rt.TypeOf; @@ -130,3 +139,5 @@ export type ConnectorServiceNowSIRTypeFields = rt.TypeOf; + +export type GetCaseConnectorsResponse = rt.TypeOf; diff --git a/x-pack/plugins/cases/common/constants.ts b/x-pack/plugins/cases/common/constants.ts index af50c851a1979..1f8d6031a1c56 100644 --- a/x-pack/plugins/cases/common/constants.ts +++ b/x-pack/plugins/cases/common/constants.ts @@ -89,6 +89,7 @@ export const INTERNAL_BULK_CREATE_ATTACHMENTS_URL = `${CASES_INTERNAL_URL}/{case_id}/attachments/_bulk_create` as const; export const INTERNAL_SUGGEST_USER_PROFILES_URL = `${CASES_INTERNAL_URL}/_suggest_user_profiles` as const; +export const INTERNAL_CONNECTORS_URL = `${CASES_INTERNAL_URL}/{case_id}/_connectors` as const; export const INTERNAL_BULK_GET_CASES_URL = `${CASES_INTERNAL_URL}/_bulk_get` as const; /** diff --git a/x-pack/plugins/cases/server/authorization/__snapshots__/audit_logger.test.ts.snap b/x-pack/plugins/cases/server/authorization/__snapshots__/audit_logger.test.ts.snap index ee6bc6e4a3681..6e824f460a722 100644 --- a/x-pack/plugins/cases/server/authorization/__snapshots__/audit_logger.test.ts.snap +++ b/x-pack/plugins/cases/server/authorization/__snapshots__/audit_logger.test.ts.snap @@ -1596,6 +1596,90 @@ Object { } `; +exports[`audit_logger log function event structure creates the correct audit event for operation: "getConnectors" with an error and entity 1`] = ` +Object { + "error": Object { + "code": "Error", + "message": "an error", + }, + "event": Object { + "action": "case_connectors_get", + "category": Array [ + "database", + ], + "outcome": "failure", + "type": Array [ + "access", + ], + }, + "kibana": Object { + "saved_object": Object { + "id": "1", + "type": "cases-user-actions", + }, + }, + "message": "Failed attempt to access cases-user-actions [id=1] as owner \\"awesome\\"", +} +`; + +exports[`audit_logger log function event structure creates the correct audit event for operation: "getConnectors" with an error but no entity 1`] = ` +Object { + "error": Object { + "code": "Error", + "message": "an error", + }, + "event": Object { + "action": "case_connectors_get", + "category": Array [ + "database", + ], + "outcome": "failure", + "type": Array [ + "access", + ], + }, + "message": "Failed attempt to access a user actions as any owners", +} +`; + +exports[`audit_logger log function event structure creates the correct audit event for operation: "getConnectors" without an error but with an entity 1`] = ` +Object { + "event": Object { + "action": "case_connectors_get", + "category": Array [ + "database", + ], + "outcome": "success", + "type": Array [ + "access", + ], + }, + "kibana": Object { + "saved_object": Object { + "id": "5", + "type": "cases-user-actions", + }, + }, + "message": "User has accessed cases-user-actions [id=5] as owner \\"super\\"", +} +`; + +exports[`audit_logger log function event structure creates the correct audit event for operation: "getConnectors" without an error or entity 1`] = ` +Object { + "event": Object { + "action": "case_connectors_get", + "category": Array [ + "database", + ], + "outcome": "success", + "type": Array [ + "access", + ], + }, + "message": "User has accessed a user actions as any owners", +} +`; + exports[`audit_logger log function event structure creates the correct audit event for operation: "getReporters" with an error and entity 1`] = ` Object { "error": Object { diff --git a/x-pack/plugins/cases/server/authorization/index.ts b/x-pack/plugins/cases/server/authorization/index.ts index 723221d361d82..0c301f372ba5d 100644 --- a/x-pack/plugins/cases/server/authorization/index.ts +++ b/x-pack/plugins/cases/server/authorization/index.ts @@ -318,6 +318,14 @@ export const Operations: Record ({ id: comment.id, @@ -150,7 +150,7 @@ export async function deleteComment( refresh: false, }); - await userActionService.createUserAction({ + await userActionService.creator.createUserAction({ type: ActionTypes.comment, action: Actions.delete, caseId: id, diff --git a/x-pack/plugins/cases/server/client/cases/create.ts b/x-pack/plugins/cases/server/client/cases/create.ts index 0da0f42b93f2f..a8f9975fee39f 100644 --- a/x-pack/plugins/cases/server/client/cases/create.ts +++ b/x-pack/plugins/cases/server/client/cases/create.ts @@ -102,7 +102,7 @@ export const create = async ( refresh: false, }); - await userActionService.createUserAction({ + await userActionService.creator.createUserAction({ type: ActionTypes.create_case, caseId: newCase.id, user, diff --git a/x-pack/plugins/cases/server/client/cases/delete.ts b/x-pack/plugins/cases/server/client/cases/delete.ts index 0b7a6a6839e5c..81f5df0d2d2b3 100644 --- a/x-pack/plugins/cases/server/client/cases/delete.ts +++ b/x-pack/plugins/cases/server/client/cases/delete.ts @@ -68,7 +68,7 @@ export async function deleteCases(ids: string[], clientArgs: CasesClientArgs): P options: { refresh: 'wait_for' }, }); - await userActionService.bulkAuditLogCaseDeletion( + await userActionService.creator.bulkAuditLogCaseDeletion( cases.saved_objects.map((caseInfo) => caseInfo.id) ); } catch (error) { diff --git a/x-pack/plugins/cases/server/client/cases/push.ts b/x-pack/plugins/cases/server/client/cases/push.ts index 9f5e9adbb4815..340a93dee2d4f 100644 --- a/x-pack/plugins/cases/server/client/cases/push.ts +++ b/x-pack/plugins/cases/server/client/cases/push.ts @@ -257,7 +257,7 @@ export const push = async ( ]); if (shouldMarkAsClosed) { - await userActionService.createUserAction({ + await userActionService.creator.createUserAction({ type: ActionTypes.status, payload: { status: CaseStatuses.closed }, user, @@ -271,7 +271,7 @@ export const push = async ( } } - await userActionService.createUserAction({ + await userActionService.creator.createUserAction({ type: ActionTypes.pushed, payload: { externalService }, user, diff --git a/x-pack/plugins/cases/server/client/cases/update.ts b/x-pack/plugins/cases/server/client/cases/update.ts index 6a304bf12e3e6..622665f139ad2 100644 --- a/x-pack/plugins/cases/server/client/cases/update.ts +++ b/x-pack/plugins/cases/server/client/cases/update.ts @@ -444,7 +444,7 @@ export const update = async ( ]; }, [] as CaseResponse[]); - await userActionService.bulkCreateUpdateCase({ + await userActionService.creator.bulkCreateUpdateCase({ originalCases: myCases.saved_objects, updatedCases: updatedCases.saved_objects, user, diff --git a/x-pack/plugins/cases/server/client/factory.ts b/x-pack/plugins/cases/server/client/factory.ts index 9816f8444e399..63f0fdcb5a12b 100644 --- a/x-pack/plugins/cases/server/client/factory.ts +++ b/x-pack/plugins/cases/server/client/factory.ts @@ -13,6 +13,7 @@ import type { SavedObjectsClientContract, IBasePath, } from '@kbn/core/server'; +import type { ISavedObjectsSerializer } from '@kbn/core-saved-objects-server'; import { SECURITY_EXTENSION_ID } from '@kbn/core-saved-objects-server'; import type { AuditLogger, @@ -119,8 +120,11 @@ export class CasesClientFactory { excludedExtensions: [SECURITY_EXTENSION_ID], }); + const savedObjectsSerializer = savedObjectsService.createSerializer(); + const services = this.createServices({ unsecuredSavedObjectsClient, + savedObjectsSerializer, esClient: scopedClusterClient, request, auditLogger, @@ -152,11 +156,13 @@ export class CasesClientFactory { private createServices({ unsecuredSavedObjectsClient, + savedObjectsSerializer, esClient, request, auditLogger, }: { unsecuredSavedObjectsClient: SavedObjectsClientContract; + savedObjectsSerializer: ISavedObjectsSerializer; esClient: ElasticsearchClient; request: KibanaRequest; auditLogger: AuditLogger; @@ -201,6 +207,7 @@ export class CasesClientFactory { log: this.logger, persistableStateAttachmentTypeRegistry: this.options.persistableStateAttachmentTypeRegistry, unsecuredSavedObjectsClient, + savedObjectsSerializer, auditLogger, }), attachmentService, diff --git a/x-pack/plugins/cases/server/client/mocks.ts b/x-pack/plugins/cases/server/client/mocks.ts index 3281cd7764240..0ca2578d107a2 100644 --- a/x-pack/plugins/cases/server/client/mocks.ts +++ b/x-pack/plugins/cases/server/client/mocks.ts @@ -83,6 +83,7 @@ type UserActionsSubClientMock = jest.Mocked; const createUserActionsSubClientMock = (): UserActionsSubClientMock => { return { getAll: jest.fn(), + getConnectors: jest.fn(), }; }; diff --git a/x-pack/plugins/cases/server/client/user_actions/client.ts b/x-pack/plugins/cases/server/client/user_actions/client.ts index 3f14a313cd8f2..bb529ae3b2c2f 100644 --- a/x-pack/plugins/cases/server/client/user_actions/client.ts +++ b/x-pack/plugins/cases/server/client/user_actions/client.ts @@ -5,19 +5,12 @@ * 2.0. */ +import type { GetCaseConnectorsResponse } from '../../../common/api'; import type { ICaseUserActionsResponse } from '../typedoc_interfaces'; import type { CasesClientArgs } from '../types'; import { get } from './get'; - -/** - * Parameters for retrieving user actions for a particular case - */ -export interface UserActionGet { - /** - * The ID of the case - */ - caseId: string; -} +import { getConnectors } from './connectors'; +import type { GetConnectorsRequest, UserActionGet } from './types'; /** * API for interacting the actions performed by a user when interacting with the cases entities. @@ -27,16 +20,19 @@ export interface UserActionsSubClient { * Retrieves all user actions for a particular case. */ getAll(clientArgs: UserActionGet): Promise; + /** + * Retrieves all the connectors used within a given case + */ + getConnectors(clientArgs: GetConnectorsRequest): Promise; } /** * Creates an API object for interacting with the user action entities - * - * @ignore */ export const createUserActionsSubClient = (clientArgs: CasesClientArgs): UserActionsSubClient => { const attachmentSubClient: UserActionsSubClient = { getAll: (params: UserActionGet) => get(params, clientArgs), + getConnectors: (params: GetConnectorsRequest) => getConnectors(params, clientArgs), }; return Object.freeze(attachmentSubClient); diff --git a/x-pack/plugins/cases/server/client/user_actions/connectors.ts b/x-pack/plugins/cases/server/client/user_actions/connectors.ts new file mode 100644 index 0000000000000..18cba75d79948 --- /dev/null +++ b/x-pack/plugins/cases/server/client/user_actions/connectors.ts @@ -0,0 +1,265 @@ +/* + * 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 { isEqual } from 'lodash'; + +import type { SavedObject } from '@kbn/core/server'; +import type { PublicMethodsOf } from '@kbn/utility-types'; +import type { ActionResult, ActionsClient } from '@kbn/actions-plugin/server'; +import type { + CaseUserActionResponse, + GetCaseConnectorsResponse, + CaseConnector, +} from '../../../common/api'; +import { GetCaseConnectorsResponseRt } from '../../../common/api'; +import { isConnectorUserAction, isCreateCaseUserAction } from '../../../common/utils/user_actions'; +import { createCaseError } from '../../common/error'; +import type { CasesClientArgs } from '..'; +import type { Authorization, OwnerEntity } from '../../authorization'; +import { Operations } from '../../authorization'; +import type { GetConnectorsRequest } from './types'; +import type { CaseConnectorActivity, PushInfo } from '../../services/user_actions/types'; +import type { CaseUserActionService } from '../../services'; + +export const getConnectors = async ( + { caseId }: GetConnectorsRequest, + clientArgs: CasesClientArgs +): Promise => { + const { + services: { userActionService }, + logger, + authorization, + actionsClient, + } = clientArgs; + + try { + const [connectors, latestUserAction] = await Promise.all([ + userActionService.getCaseConnectorInformation(caseId), + userActionService.getMostRecentUserAction(caseId), + ]); + + await checkConnectorsAuthorization({ authorization, connectors, latestUserAction }); + + const results = await getConnectorsInfo({ + caseId, + actionsClient, + connectors, + latestUserAction, + userActionService, + }); + + return GetCaseConnectorsResponseRt.encode(results); + } catch (error) { + throw createCaseError({ + message: `Failed to retrieve the case connectors case id: ${caseId}: ${error}`, + error, + logger, + }); + } +}; + +const checkConnectorsAuthorization = async ({ + connectors, + latestUserAction, + authorization, +}: { + connectors: CaseConnectorActivity[]; + latestUserAction?: SavedObject; + authorization: PublicMethodsOf; +}) => { + const entities: OwnerEntity[] = latestUserAction + ? [{ owner: latestUserAction.attributes.owner, id: latestUserAction.id }] + : []; + + for (const connector of connectors) { + entities.push({ + owner: connector.fields.attributes.owner, + id: connector.connectorId, + }); + + if (connector.push) { + entities.push({ + owner: connector.push.attributes.owner, + id: connector.connectorId, + }); + } + } + + await authorization.ensureAuthorized({ + entities, + operation: Operations.getConnectors, + }); +}; + +interface EnrichedPushInfo { + pushDate: Date; + connectorFieldsUsedInPush: CaseConnector; +} + +const getConnectorsInfo = async ({ + caseId, + connectors, + latestUserAction, + actionsClient, + userActionService, +}: { + caseId: string; + connectors: CaseConnectorActivity[]; + latestUserAction?: SavedObject; + actionsClient: PublicMethodsOf; + userActionService: CaseUserActionService; +}): Promise => { + const connectorIds = connectors.map((connector) => connector.connectorId); + + const [pushInfo, actionConnectors] = await Promise.all([ + getPushInfo({ caseId, activity: connectors, userActionService }), + actionsClient.getBulk(connectorIds), + ]); + + return createConnectorInfoResult({ actionConnectors, connectors, pushInfo, latestUserAction }); +}; + +const getPushInfo = async ({ + caseId, + activity, + userActionService, +}: { + caseId: string; + activity: CaseConnectorActivity[]; + userActionService: CaseUserActionService; +}): Promise> => { + const pushRequest: PushInfo[] = []; + + for (const connectorInfo of activity) { + const pushCreatedAt = getDate(connectorInfo.push?.attributes.created_at); + + if (connectorInfo.push != null && pushCreatedAt != null) { + pushRequest.push({ connectorId: connectorInfo.connectorId, date: pushCreatedAt }); + } + } + + const connectorFieldsForPushes = await userActionService.getConnectorFieldsBeforeLatestPush( + caseId, + pushRequest + ); + + const enrichedPushInfo = new Map(); + for (const request of pushRequest) { + const connectorFieldsSO = connectorFieldsForPushes.get(request.connectorId); + const connectorFields = getConnectorInfoFromSavedObject(connectorFieldsSO); + + if (connectorFields != null) { + enrichedPushInfo.set(request.connectorId, { + pushDate: request.date, + connectorFieldsUsedInPush: connectorFields, + }); + } + } + + return enrichedPushInfo; +}; + +const getDate = (timestamp: string | undefined): Date | undefined => { + if (timestamp == null) { + return; + } + + const date = new Date(timestamp); + + if (isDateValid(date)) { + return date; + } +}; + +const isDateValid = (date: Date): boolean => { + return !isNaN(date.getTime()); +}; + +const getConnectorInfoFromSavedObject = ( + savedObject: SavedObject | undefined +): CaseConnector | undefined => { + if ( + savedObject != null && + (isConnectorUserAction(savedObject.attributes) || + isCreateCaseUserAction(savedObject.attributes)) + ) { + return savedObject.attributes.payload.connector; + } +}; + +const createConnectorInfoResult = ({ + actionConnectors, + connectors, + pushInfo, + latestUserAction, +}: { + actionConnectors: ActionResult[]; + connectors: CaseConnectorActivity[]; + pushInfo: Map; + latestUserAction?: SavedObject; +}) => { + const results: GetCaseConnectorsResponse = {}; + + for (let i = 0; i < connectors.length; i++) { + const connectorDetails = actionConnectors[i]; + const aggregationConnector = connectors[i]; + const connector = getConnectorInfoFromSavedObject(aggregationConnector.fields); + + const latestUserActionCreatedAt = getDate(latestUserAction?.attributes.created_at); + + if (connector != null) { + const enrichedPushInfo = pushInfo.get(aggregationConnector.connectorId); + const needsToBePushed = hasDataToPush({ + connector, + pushInfo: enrichedPushInfo, + latestUserActionDate: latestUserActionCreatedAt, + }); + + results[connector.id] = { + ...connector, + name: connectorDetails.name, + needsToBePushed, + latestPushDate: enrichedPushInfo?.pushDate.toISOString(), + hasBeenPushed: hasBeenPushed(enrichedPushInfo), + }; + } + } + + return results; +}; + +/** + * The algorithm to determine if a specific connector within a case needs to be pushed is as follows: + * 1. Check to see if the connector has been used to push, if it hasn't then we need to push + * 2. Check to see if the most recent connector fields are different than the connector fields used in the most recent push, + * if they are different then we need to push + * 3. Check to see if the most recent valid user action (a valid user action is one that changes the title, description, + * tags, or creation of a comment) was created after the most recent push (aka did the user do something new that needs + * to be pushed) + */ +const hasDataToPush = ({ + connector, + pushInfo, + latestUserActionDate, +}: { + connector: CaseConnector; + pushInfo?: EnrichedPushInfo; + latestUserActionDate?: Date; +}): boolean => { + return ( + /** + * This isEqual call satisfies the first two steps of the algorithm above because if a push never occurred then the + * push fields will be undefined which will not equal the latest connector fields anyway. + */ + !isEqual(connector, pushInfo?.connectorFieldsUsedInPush) || + (pushInfo != null && latestUserActionDate != null && latestUserActionDate > pushInfo.pushDate) + ); +}; + +const hasBeenPushed = (pushInfo: EnrichedPushInfo | undefined): boolean => { + return pushInfo != null; +}; diff --git a/x-pack/plugins/cases/server/client/user_actions/get.ts b/x-pack/plugins/cases/server/client/user_actions/get.ts index 3b1addfe7c6c5..63711419ad3b9 100644 --- a/x-pack/plugins/cases/server/client/user_actions/get.ts +++ b/x-pack/plugins/cases/server/client/user_actions/get.ts @@ -11,7 +11,7 @@ import { CaseUserActionsResponseRt } from '../../../common/api'; import { createCaseError } from '../../common/error'; import type { CasesClientArgs } from '..'; import { Operations } from '../../authorization'; -import type { UserActionGet } from './client'; +import type { UserActionGet } from './types'; export const get = async ( { caseId }: UserActionGet, diff --git a/x-pack/plugins/cases/server/client/user_actions/types.ts b/x-pack/plugins/cases/server/client/user_actions/types.ts new file mode 100644 index 0000000000000..a974c5136047c --- /dev/null +++ b/x-pack/plugins/cases/server/client/user_actions/types.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + +/** + * Parameters for retrieving user actions for a particular case + */ +export interface UserActionGet { + /** + * The ID of the case + */ + caseId: string; +} + +export type GetConnectorsRequest = UserActionGet; diff --git a/x-pack/plugins/cases/server/common/models/case_with_comments.ts b/x-pack/plugins/cases/server/common/models/case_with_comments.ts index 1cc40b48d51e6..62d6b44b613f8 100644 --- a/x-pack/plugins/cases/server/common/models/case_with_comments.ts +++ b/x-pack/plugins/cases/server/common/models/case_with_comments.ts @@ -182,7 +182,7 @@ export class CaseCommentModel { ) { const { id, version, ...queryRestAttributes } = updateRequest; - await this.params.services.userActionService.createUserAction({ + await this.params.services.userActionService.creator.createUserAction({ type: ActionTypes.comment, action: Actions.update, caseId: this.caseInfo.id, @@ -335,7 +335,7 @@ export class CaseCommentModel { comment: SavedObject, req: CommentRequest ) { - await this.params.services.userActionService.createUserAction({ + await this.params.services.userActionService.creator.createUserAction({ type: ActionTypes.comment, action: Actions.create, caseId: this.caseInfo.id, @@ -349,7 +349,7 @@ export class CaseCommentModel { } private async bulkCreateCommentUserAction(attachments: Array<{ id: string } & CommentRequest>) { - await this.params.services.userActionService.bulkCreateAttachmentCreation({ + await this.params.services.userActionService.creator.bulkCreateAttachmentCreation({ caseId: this.caseInfo.id, attachments: attachments.map(({ id, ...attachment }) => ({ id, diff --git a/x-pack/plugins/cases/server/routes/api/get_internal_routes.ts b/x-pack/plugins/cases/server/routes/api/get_internal_routes.ts index 096a57af6b8ca..ca1f44706caf9 100644 --- a/x-pack/plugins/cases/server/routes/api/get_internal_routes.ts +++ b/x-pack/plugins/cases/server/routes/api/get_internal_routes.ts @@ -6,6 +6,7 @@ */ import type { UserProfileService } from '../../services'; +import { getConnectorsRoute } from './internal/get_connectors'; import { bulkCreateAttachmentsRoute } from './internal/bulk_create_attachments'; import { bulkGetCasesRoute } from './internal/bulk_get_cases'; import { suggestUserProfilesRoute } from './internal/suggest_user_profiles'; @@ -15,5 +16,6 @@ export const getInternalRoutes = (userProfileService: UserProfileService) => [ bulkCreateAttachmentsRoute, suggestUserProfilesRoute(userProfileService), + getConnectorsRoute, bulkGetCasesRoute, ] as CaseRoute[]; diff --git a/x-pack/plugins/cases/server/routes/api/internal/get_connectors.ts b/x-pack/plugins/cases/server/routes/api/internal/get_connectors.ts new file mode 100644 index 0000000000000..ac48e17461fad --- /dev/null +++ b/x-pack/plugins/cases/server/routes/api/internal/get_connectors.ts @@ -0,0 +1,37 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { INTERNAL_CONNECTORS_URL } from '../../../../common/constants'; +import { createCaseError } from '../../../common/error'; +import { createCasesRoute } from '../create_cases_route'; + +export const getConnectorsRoute = createCasesRoute({ + method: 'get', + path: INTERNAL_CONNECTORS_URL, + params: { + params: schema.object({ + case_id: schema.string(), + }), + }, + handler: async ({ context, request, response }) => { + try { + const casesContext = await context.cases; + const casesClient = await casesContext.getCasesClient(); + const caseId = request.params.case_id; + + return response.ok({ + body: await casesClient.userActions.getConnectors({ caseId }), + }); + } catch (error) { + throw createCaseError({ + message: `Failed to retrieve connectors in route case id: ${request.params.case_id}: ${error}`, + error, + }); + } + }, +}); diff --git a/x-pack/plugins/cases/server/services/mocks.ts b/x-pack/plugins/cases/server/services/mocks.ts index 125fbc7ec9650..11ce2711bbbae 100644 --- a/x-pack/plugins/cases/server/services/mocks.ts +++ b/x-pack/plugins/cases/server/services/mocks.ts @@ -16,11 +16,13 @@ import type { } from '.'; import type { LicensingService } from './licensing'; import type { EmailNotificationService } from './notifications/email_notification_service'; +import type { UserActionPersister } from './user_actions/operations/create'; export type CaseServiceMock = jest.Mocked; export type CaseConfigureServiceMock = jest.Mocked; export type ConnectorMappingsServiceMock = jest.Mocked; export type CaseUserActionServiceMock = jest.Mocked; +export type CaseUserActionPersisterServiceMock = jest.Mocked; export type AlertServiceMock = jest.Mocked; export type AttachmentServiceMock = jest.Mocked; export type LicensingServiceMock = jest.Mocked; @@ -73,13 +75,28 @@ export const connectorMappingsServiceMock = (): ConnectorMappingsServiceMock => return service as unknown as ConnectorMappingsServiceMock; }; -export const createUserActionServiceMock = (): CaseUserActionServiceMock => { - const service: PublicMethodsOf = { +const createUserActionPersisterServiceMock = (): CaseUserActionPersisterServiceMock => { + const service: PublicMethodsOf = { bulkAuditLogCaseDeletion: jest.fn(), bulkCreateUpdateCase: jest.fn(), bulkCreateAttachmentDeletion: jest.fn(), bulkCreateAttachmentCreation: jest.fn(), createUserAction: jest.fn(), + }; + + return service as unknown as CaseUserActionPersisterServiceMock; +}; + +type FakeUserActionService = PublicMethodsOf & { + creator: CaseUserActionPersisterServiceMock; +}; + +export const createUserActionServiceMock = (): CaseUserActionServiceMock => { + const service: FakeUserActionService = { + creator: createUserActionPersisterServiceMock(), + getConnectorFieldsBeforeLatestPush: jest.fn(), + getMostRecentUserAction: jest.fn(), + getCaseConnectorInformation: jest.fn(), getAll: jest.fn(), findStatusChanges: jest.fn(), getUniqueConnectors: jest.fn(), diff --git a/x-pack/plugins/cases/server/services/user_actions/index.test.ts b/x-pack/plugins/cases/server/services/user_actions/index.test.ts index e2aa6192cdccf..f5fefebfc41b7 100644 --- a/x-pack/plugins/cases/server/services/user_actions/index.test.ts +++ b/x-pack/plugins/cases/server/services/user_actions/index.test.ts @@ -64,6 +64,7 @@ import { createPersistableStateAttachmentTypeRegistryMock, persistableStateAttachment, } from '../../attachment_framework/mocks'; +import { serializerMock } from '@kbn/core-saved-objects-base-server-mocks'; const createConnectorUserAction = ( overrides?: Partial @@ -661,6 +662,8 @@ describe('CaseUserActionService', () => { }; const mockAuditLogger = auditLoggerMock.create(); + const soSerializerMock = serializerMock.create(); + beforeEach(() => { jest.clearAllMocks(); service = new CaseUserActionService({ @@ -668,13 +671,14 @@ describe('CaseUserActionService', () => { log: mockLogger, persistableStateAttachmentTypeRegistry, auditLogger: mockAuditLogger, + savedObjectsSerializer: soSerializerMock, }); }); describe('createUserAction', () => { describe('create case', () => { it('creates a create case user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: casePayload, type: ActionTypes.create_case, @@ -726,7 +730,7 @@ describe('CaseUserActionService', () => { }); it('logs a create case user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: casePayload, type: ActionTypes.create_case, @@ -760,7 +764,7 @@ describe('CaseUserActionService', () => { describe('status', () => { it('creates an update status user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: { status: CaseStatuses.closed }, type: ActionTypes.status, @@ -785,7 +789,7 @@ describe('CaseUserActionService', () => { }); it('logs an update status user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: { status: CaseStatuses.closed }, type: ActionTypes.status, @@ -820,7 +824,7 @@ describe('CaseUserActionService', () => { describe('severity', () => { it('creates an update severity user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: { severity: CaseSeverity.MEDIUM }, type: ActionTypes.severity, @@ -845,7 +849,7 @@ describe('CaseUserActionService', () => { }); it('logs an update severity user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: { severity: CaseSeverity.MEDIUM }, type: ActionTypes.severity, @@ -880,7 +884,7 @@ describe('CaseUserActionService', () => { describe('push', () => { it('creates a push user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: { externalService }, type: ActionTypes.pushed, @@ -924,7 +928,7 @@ describe('CaseUserActionService', () => { }); it('logs a push user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: { externalService }, type: ActionTypes.pushed, @@ -961,7 +965,7 @@ describe('CaseUserActionService', () => { it.each([[Actions.create], [Actions.delete], [Actions.update]])( 'creates a comment user action of action: %s', async (action) => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, type: ActionTypes.comment, action, @@ -1002,7 +1006,7 @@ describe('CaseUserActionService', () => { it.each([[Actions.create], [Actions.delete], [Actions.update]])( 'logs a comment user action of action: %s', async (action) => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, type: ActionTypes.comment, action, @@ -1020,7 +1024,7 @@ describe('CaseUserActionService', () => { describe('bulkAuditLogCaseDeletion', () => { it('logs a delete case audit log message', async () => { - await service.bulkAuditLogCaseDeletion(['1', '2']); + await service.creator.bulkAuditLogCaseDeletion(['1', '2']); expect(unsecuredSavedObjectsClient.bulkCreate).not.toHaveBeenCalled(); @@ -1076,7 +1080,7 @@ describe('CaseUserActionService', () => { describe('bulkCreateUpdateCase', () => { it('creates the correct user actions when bulk updating cases', async () => { - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases, updatedCases, @@ -1244,7 +1248,7 @@ describe('CaseUserActionService', () => { }); it('logs the correct user actions when bulk updating cases', async () => { - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases, updatedCases, @@ -1427,7 +1431,7 @@ describe('CaseUserActionService', () => { }); it('creates the correct user actions when an assignee is added', async () => { - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases, updatedCases: updatedAssigneesCases, @@ -1474,7 +1478,7 @@ describe('CaseUserActionService', () => { }); it('logs the correct user actions when an assignee is added', async () => { - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases, updatedCases: updatedAssigneesCases, @@ -1520,7 +1524,7 @@ describe('CaseUserActionService', () => { }, ]; - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases: originalCasesWithAssignee, updatedCases: casesWithAssigneeRemoved, @@ -1577,7 +1581,7 @@ describe('CaseUserActionService', () => { }, ]; - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases: originalCasesWithAssignee, updatedCases: casesWithAssigneeRemoved, @@ -1623,7 +1627,7 @@ describe('CaseUserActionService', () => { }, ]; - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases: originalCasesWithAssignee, updatedCases: caseAssignees, @@ -1708,7 +1712,7 @@ describe('CaseUserActionService', () => { }, ]; - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases: originalCasesWithAssignee, updatedCases: caseAssignees, @@ -1765,7 +1769,7 @@ describe('CaseUserActionService', () => { }); it('creates the correct user actions when tags are added and removed', async () => { - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases, updatedCases: updatedTagsCases, @@ -1837,7 +1841,7 @@ describe('CaseUserActionService', () => { }); it('logs the correct user actions when tags are added and removed', async () => { - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases, updatedCases: updatedTagsCases, @@ -1896,7 +1900,7 @@ describe('CaseUserActionService', () => { describe('bulkCreateAttachmentDeletion', () => { it('creates delete comment user action', async () => { - await service.bulkCreateAttachmentDeletion({ + await service.creator.bulkCreateAttachmentDeletion({ ...commonArgs, attachments, }); @@ -1956,7 +1960,7 @@ describe('CaseUserActionService', () => { }); it('logs delete comment user action', async () => { - await service.bulkCreateAttachmentDeletion({ + await service.creator.bulkCreateAttachmentDeletion({ ...commonArgs, attachments, }); diff --git a/x-pack/plugins/cases/server/services/user_actions/index.ts b/x-pack/plugins/cases/server/services/user_actions/index.ts index 9cf0095019c97..31060ebb86d28 100644 --- a/x-pack/plugins/cases/server/services/user_actions/index.ts +++ b/x-pack/plugins/cases/server/services/user_actions/index.ts @@ -5,40 +5,26 @@ * 2.0. */ -import { get, isEmpty } from 'lodash'; - import type { - Logger, SavedObject, SavedObjectReference, - SavedObjectsBulkResponse, - SavedObjectsClientContract, SavedObjectsFindResponse, - SavedObjectsUpdateResponse, + SavedObjectsRawDoc, } from '@kbn/core/server'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { KueryNode } from '@kbn/es-query'; -import type { AuditLogger } from '@kbn/security-plugin/server'; import { isCommentRequestTypePersistableState } from '../../../common/utils/attachments'; import { isConnectorUserAction, isPushedUserAction, - isUserActionType, isCreateCaseUserAction, isCommentUserAction, } from '../../../common/utils/user_actions'; import type { - ActionTypeValues, - CaseAttributes, CaseUserActionAttributes, CaseUserActionAttributesWithoutConnectorId, CaseUserActionResponse, - CaseUserProfile, - CaseAssignees, - CommentRequest, - User, - UserAction as Action, } from '../../../common/api'; import { Actions, ActionTypes, NONE_CONNECTOR_ID } from '../../../common/api'; import { @@ -55,364 +41,466 @@ import { PUSH_CONNECTOR_ID_REFERENCE_NAME, } from '../../common/constants'; import { findConnectorIdReference } from '../transform'; -import { buildFilter, combineFilters, arraysDifference } from '../../client/utils'; -import type { - Attributes, - BuilderParameters, - CommonArguments, - CreateUserAction, - UserActionEvent, - UserActionParameters, -} from './types'; -import { BuilderFactory } from './builder_factory'; +import { buildFilter, combineFilters } from '../../client/utils'; +import type { CaseConnectorActivity, CaseConnectorFields, PushInfo, ServiceContext } from './types'; import { defaultSortField, isCommentRequestTypeExternalReferenceSO } from '../../common/utils'; import type { PersistableStateAttachmentTypeRegistry } from '../../attachment_framework/persistable_state_registry'; import { injectPersistableReferencesToSO } from '../../attachment_framework/so_references'; -import type { IndexRefresh } from '../types'; -import { isAssigneesArray, isStringArray } from './type_guards'; -import type { CaseSavedObject } from '../../common/types'; -import { UserActionAuditLogger } from './audit_logger'; +import { UserActionPersister } from './operations/create'; export interface UserActionItem { attributes: CaseUserActionAttributesWithoutConnectorId; references: SavedObjectReference[]; } -interface PostCaseUserActionArgs extends IndexRefresh { - actions: UserActionEvent[]; +interface MostRecentResults { + mostRecent: { + hits: { + total: number; + hits: SavedObjectsRawDoc[]; + }; + }; } -interface CreateUserActionES extends IndexRefresh { - attributes: T; - references: SavedObjectReference[]; +interface ConnectorActivityAggsResult { + references: { + connectors: { + ids: { + buckets: Array<{ + key: string; + reverse: { + connectorActivity: { + buckets: { + changeConnector: MostRecentResults; + createCase: MostRecentResults; + pushInfo: MostRecentResults; + }; + }; + }; + }>; + }; + }; + }; } -type CommonUserActionArgs = CommonArguments; - -interface GetUserActionItemByDifference extends CommonUserActionArgs { - field: string; - originalValue: unknown; - newValue: unknown; +interface ConnectorFieldsBeforePushAggsResult { + references: { + connectors: { + reverse: { + ids: { + buckets: Record; + }; + }; + }; + }; } -interface TypedUserActionDiffedItems extends GetUserActionItemByDifference { - originalValue: T[]; - newValue: T[]; -} +export class CaseUserActionService { + private readonly _creator: UserActionPersister; -interface BulkCreateBulkUpdateCaseUserActions extends IndexRefresh { - originalCases: CaseSavedObject[]; - updatedCases: Array>; - user: User; -} + constructor(private readonly context: ServiceContext) { + this._creator = new UserActionPersister(context); + } -interface BulkCreateAttachmentUserAction extends Omit, IndexRefresh { - attachments: Array<{ id: string; owner: string; attachment: CommentRequest }>; -} + public get creator() { + return this._creator; + } -type CreateUserActionClient = CreateUserAction & - CommonUserActionArgs & - IndexRefresh; + public async getConnectorFieldsBeforeLatestPush( + caseId: string, + pushes: PushInfo[] + ): Promise { + try { + this.context.log.debug( + `Attempting to retrieve the connector fields before the last push for case id: ${caseId}` + ); -type CreatePayloadFunction = ( - items: Item[] -) => UserActionParameters['payload']; + if (pushes.length <= 0) { + return new Map(); + } -export class CaseUserActionService { - private static readonly userActionFieldsAllowed: Set = new Set(Object.keys(ActionTypes)); - - private readonly unsecuredSavedObjectsClient: SavedObjectsClientContract; - private readonly builderFactory: BuilderFactory; - private readonly persistableStateAttachmentTypeRegistry: PersistableStateAttachmentTypeRegistry; - private readonly log: Logger; - private readonly auditLogger: UserActionAuditLogger; - - constructor({ - log, - persistableStateAttachmentTypeRegistry, - unsecuredSavedObjectsClient, - auditLogger, - }: { - log: Logger; - persistableStateAttachmentTypeRegistry: PersistableStateAttachmentTypeRegistry; - unsecuredSavedObjectsClient: SavedObjectsClientContract; - auditLogger: AuditLogger; - }) { - this.log = log; - this.unsecuredSavedObjectsClient = unsecuredSavedObjectsClient; - this.persistableStateAttachmentTypeRegistry = persistableStateAttachmentTypeRegistry; - - this.builderFactory = new BuilderFactory({ - persistableStateAttachmentTypeRegistry: this.persistableStateAttachmentTypeRegistry, - }); - - this.auditLogger = new UserActionAuditLogger(auditLogger); - } + const connectorsFilter = buildFilter({ + filters: [ActionTypes.connector, ActionTypes.create_case], + field: 'type', + operator: 'or', + type: CASE_USER_ACTION_SAVED_OBJECT, + }); - private getUserActionItemByDifference(params: GetUserActionItemByDifference): UserActionEvent[] { - const { field, originalValue, newValue, caseId, owner, user } = params; - - if (!CaseUserActionService.userActionFieldsAllowed.has(field)) { - return []; - } else if ( - field === ActionTypes.assignees && - isAssigneesArray(originalValue) && - isAssigneesArray(newValue) - ) { - return this.buildAssigneesUserActions({ ...params, originalValue, newValue }); - } else if ( - field === ActionTypes.tags && - isStringArray(originalValue) && - isStringArray(newValue) - ) { - return this.buildTagsUserActions({ ...params, originalValue, newValue }); - } else if (isUserActionType(field) && newValue != null) { - const userActionBuilder = this.builderFactory.getBuilder(ActionTypes[field]); - const fieldUserAction = userActionBuilder?.build({ - caseId, - owner, - user, - payload: { [field]: newValue }, + const response = await this.context.unsecuredSavedObjectsClient.find< + CaseUserActionAttributesWithoutConnectorId, + ConnectorFieldsBeforePushAggsResult + >({ + type: CASE_USER_ACTION_SAVED_OBJECT, + hasReference: { type: CASE_SAVED_OBJECT, id: caseId }, + page: 1, + perPage: 1, + sortField: defaultSortField, + aggs: CaseUserActionService.buildConnectorFieldsUsedInPushAggs(pushes), + filter: connectorsFilter, }); - return fieldUserAction ? [fieldUserAction] : []; + return this.createCaseConnectorFieldsUsedInPushes(response.aggregations); + } catch (error) { + this.context.log.error( + `Error while retrieving the connector fields before the last push: ${caseId}: ${error}` + ); + throw error; } - - return []; } - private buildAssigneesUserActions(params: TypedUserActionDiffedItems) { - const createPayload: CreatePayloadFunction = ( - items: CaseAssignees - ) => ({ assignees: items }); - - return this.buildAddDeleteUserActions(params, createPayload, ActionTypes.assignees); - } + private static buildConnectorFieldsUsedInPushAggs( + pushes: PushInfo[] + ): Record { + const filters: estypes.AggregationsBuckets = {}; - private buildTagsUserActions(params: TypedUserActionDiffedItems) { - const createPayload: CreatePayloadFunction = ( - items: string[] - ) => ({ - tags: items, - }); + /** + * Group the user actions by the unique connector ids and bound the time range + * for that connector's push event. We want to search for the fields before the push timestamp. + */ + for (const push of pushes) { + filters[push.connectorId] = { + bool: { + filter: [ + { + // Search for connector field user action prior to the push occurrence + range: { + [`${CASE_USER_ACTION_SAVED_OBJECT}.created_at`]: { + lt: push.date.toISOString(), + }, + }, + }, + { + nested: { + path: `${CASE_USER_ACTION_SAVED_OBJECT}.references`, + query: { + bool: { + filter: [ + { + // We only want to search a time frame for a specific connector id + term: { + [`${CASE_USER_ACTION_SAVED_OBJECT}.references.id`]: { + value: push.connectorId, + }, + }, + }, + ], + }, + }, + }, + }, + ], + }, + }; + } - return this.buildAddDeleteUserActions(params, createPayload, ActionTypes.tags); + return { + references: { + nested: { + path: `${CASE_USER_ACTION_SAVED_OBJECT}.references`, + }, + aggregations: { + connectors: { + filter: { + // Only search for user actions that have a connector reference aka a reference with type action + term: { + [`${CASE_USER_ACTION_SAVED_OBJECT}.references.type`]: 'action', + }, + }, + aggregations: { + reverse: { + reverse_nested: {}, + aggregations: { + ids: { + filters: { + filters, + }, + aggregations: { + mostRecent: { + top_hits: { + sort: [ + { + [`${CASE_USER_ACTION_SAVED_OBJECT}.created_at`]: { + order: 'desc', + }, + }, + ], + size: 1, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }; } - private buildAddDeleteUserActions( - params: TypedUserActionDiffedItems, - createPayload: CreatePayloadFunction, - actionType: ActionType - ) { - const { originalValue, newValue } = params; - const compareValues = arraysDifference(originalValue, newValue); - - const addUserAction = this.buildUserAction({ - commonArgs: params, - actionType, - action: Actions.add, - createPayload, - modifiedItems: compareValues?.addedItems, - }); - const deleteUserAction = this.buildUserAction({ - commonArgs: params, - actionType, - action: Actions.delete, - createPayload, - modifiedItems: compareValues?.deletedItems, - }); - - return [ - ...(addUserAction ? [addUserAction] : []), - ...(deleteUserAction ? [deleteUserAction] : []), - ]; - } + private createCaseConnectorFieldsUsedInPushes( + aggsResults?: ConnectorFieldsBeforePushAggsResult + ): CaseConnectorFields { + const connectorFields: CaseConnectorFields = new Map(); - private buildUserAction({ - commonArgs, - actionType, - action, - createPayload, - modifiedItems, - }: { - commonArgs: CommonUserActionArgs; - actionType: ActionType; - action: Action; - createPayload: CreatePayloadFunction; - modifiedItems?: Item[] | null; - }) { - const userActionBuilder = this.builderFactory.getBuilder(actionType); - - if (!userActionBuilder || !modifiedItems || modifiedItems.length <= 0) { - return; + if (!aggsResults) { + return connectorFields; } - const { caseId, owner, user } = commonArgs; + for (const connectorId of Object.keys(aggsResults.references.connectors.reverse.ids.buckets)) { + const fields = aggsResults.references.connectors.reverse.ids.buckets[connectorId]; + + if (fields.mostRecent.hits.hits.length > 0) { + const rawFieldsDoc = fields.mostRecent.hits.hits[0]; + const doc = + this.context.savedObjectsSerializer.rawToSavedObject( + rawFieldsDoc + ); + + const fieldsDoc = transformToExternalModel( + doc, + this.context.persistableStateAttachmentTypeRegistry + ); - const userAction = userActionBuilder.build({ - action, - caseId, - user, - owner, - payload: createPayload(modifiedItems), - }); + connectorFields.set(connectorId, fieldsDoc); + } + } - return userAction; + return connectorFields; } - public async bulkAuditLogCaseDeletion(caseIds: string[]) { - this.log.debug(`Attempting to log bulk case deletion`); + public async getMostRecentUserAction( + caseId: string + ): Promise | undefined> { + try { + this.context.log.debug( + `Attempting to retrieve the most recent user action for case id: ${caseId}` + ); + + const id = caseId; + const type = CASE_SAVED_OBJECT; - for (const id of caseIds) { - this.auditLogger.log({ - getMessage: () => `User deleted case id: ${id}`, - action: Actions.delete, - descriptiveAction: 'case_user_action_delete_case', - savedObjectId: id, - savedObjectType: CASE_SAVED_OBJECT, + const connectorsFilter = buildFilter({ + filters: [ + ActionTypes.comment, + ActionTypes.description, + ActionTypes.tags, + ActionTypes.title, + ], + field: 'type', + operator: 'or', + type: CASE_USER_ACTION_SAVED_OBJECT, }); + + const userActions = + await this.context.unsecuredSavedObjectsClient.find( + { + type: CASE_USER_ACTION_SAVED_OBJECT, + hasReference: { type, id }, + page: 1, + perPage: 1, + sortField: 'created_at', + sortOrder: 'desc', + filter: connectorsFilter, + } + ); + + if (userActions.saved_objects.length <= 0) { + return; + } + + return transformToExternalModel( + userActions.saved_objects[0], + this.context.persistableStateAttachmentTypeRegistry + ); + } catch (error) { + this.context.log.error( + `Error while retrieving the most recent user action for case id: ${caseId}: ${error}` + ); + throw error; } } - public async bulkCreateUpdateCase({ - originalCases, - updatedCases, - user, - refresh, - }: BulkCreateBulkUpdateCaseUserActions): Promise { - const builtUserActions = updatedCases.reduce((acc, updatedCase) => { - const originalCase = originalCases.find(({ id }) => id === updatedCase.id); - - if (originalCase == null) { - return acc; - } + public async getCaseConnectorInformation(caseId: string): Promise { + try { + this.context.log.debug(`Attempting to find connector information for case id: ${caseId}`); - const caseId = updatedCase.id; - const owner = originalCase.attributes.owner; - - const userActions: UserActionEvent[] = []; - const updatedFields = Object.keys(updatedCase.attributes); - - updatedFields - .filter((field) => CaseUserActionService.userActionFieldsAllowed.has(field)) - .forEach((field) => { - const originalValue = get(originalCase, ['attributes', field]); - const newValue = get(updatedCase, ['attributes', field]); - userActions.push( - ...this.getUserActionItemByDifference({ - field, - originalValue, - newValue, - user, - owner, - caseId, - }) - ); - }); + const connectorsFilter = buildFilter({ + filters: [ActionTypes.connector, ActionTypes.create_case, ActionTypes.pushed], + field: 'type', + operator: 'or', + type: CASE_USER_ACTION_SAVED_OBJECT, + }); - return [...acc, ...userActions]; - }, []); + const response = await this.context.unsecuredSavedObjectsClient.find< + CaseUserActionAttributesWithoutConnectorId, + ConnectorActivityAggsResult + >({ + type: CASE_USER_ACTION_SAVED_OBJECT, + hasReference: { type: CASE_SAVED_OBJECT, id: caseId }, + page: 1, + perPage: 1, + sortField: defaultSortField, + aggs: CaseUserActionService.buildConnectorInfoAggs(), + filter: connectorsFilter, + }); - await this.bulkCreateAndLog({ - userActions: builtUserActions, - refresh, - }); + return this.createCaseConnectorInformation(response.aggregations); + } catch (error) { + this.context.log.error( + `Error while retrieving the connector information for case id: ${caseId} ${error}` + ); + throw error; + } } - private async bulkCreateAttachment({ - caseId, - attachments, - user, - action = Actions.create, - refresh, - }: BulkCreateAttachmentUserAction): Promise { - this.log.debug(`Attempting to create a bulk create case user action`); - const userActions = attachments.reduce((acc, attachment) => { - const userActionBuilder = this.builderFactory.getBuilder(ActionTypes.comment); - const commentUserAction = userActionBuilder?.build({ - action, - caseId, - user, - owner: attachment.owner, - attachmentId: attachment.id, - payload: { attachment: attachment.attachment }, - }); + private createCaseConnectorInformation( + aggsResults?: ConnectorActivityAggsResult + ): CaseConnectorActivity[] { + const caseConnectorInfo: CaseConnectorActivity[] = []; - if (commentUserAction == null) { - return acc; + if (!aggsResults) { + return caseConnectorInfo; + } + + for (const connectorInfo of aggsResults.references.connectors.ids.buckets) { + const changeConnector = connectorInfo.reverse.connectorActivity.buckets.changeConnector; + const createCase = connectorInfo.reverse.connectorActivity.buckets.createCase; + let rawFieldsDoc: SavedObjectsRawDoc | undefined; + + if (changeConnector.mostRecent.hits.hits.length > 0) { + rawFieldsDoc = changeConnector.mostRecent.hits.hits[0]; + } else if (createCase.mostRecent.hits.hits.length > 0) { + /** + * If there is ever a connector update user action that takes precedence over the information stored + * in the create case user action because it indicates that the connector's fields were changed + */ + rawFieldsDoc = createCase.mostRecent.hits.hits[0]; } - return [...acc, commentUserAction]; - }, []); + let fieldsDoc: SavedObject | undefined; + if (rawFieldsDoc != null) { + const doc = + this.context.savedObjectsSerializer.rawToSavedObject( + rawFieldsDoc + ); + + fieldsDoc = transformToExternalModel( + doc, + this.context.persistableStateAttachmentTypeRegistry + ); + } - await this.bulkCreateAndLog({ - userActions, - refresh, - }); - } + const pushInfo = connectorInfo.reverse.connectorActivity.buckets.pushInfo; + let pushDoc: SavedObject | undefined; - public async bulkCreateAttachmentDeletion({ - caseId, - attachments, - user, - refresh, - }: BulkCreateAttachmentUserAction): Promise { - await this.bulkCreateAttachment({ - caseId, - attachments, - user, - action: Actions.delete, - refresh, - }); - } + if (pushInfo.mostRecent.hits.hits.length > 0) { + const rawPushDoc = pushInfo.mostRecent.hits.hits[0]; - public async bulkCreateAttachmentCreation({ - caseId, - attachments, - user, - refresh, - }: BulkCreateAttachmentUserAction): Promise { - await this.bulkCreateAttachment({ - caseId, - attachments, - user, - action: Actions.create, - refresh, - }); - } + const doc = + this.context.savedObjectsSerializer.rawToSavedObject( + rawPushDoc + ); - public async createUserAction({ - action, - type, - caseId, - user, - owner, - payload, - connectorId, - attachmentId, - refresh, - }: CreateUserActionClient) { - try { - this.log.debug(`Attempting to create a user action of type: ${type}`); - const userActionBuilder = this.builderFactory.getBuilder(type); - - const userAction = userActionBuilder?.build({ - action, - caseId, - user, - owner, - connectorId, - attachmentId, - payload, - }); + pushDoc = transformToExternalModel( + doc, + this.context.persistableStateAttachmentTypeRegistry + ); + } - if (userAction) { - await this.createAndLog({ userAction, refresh }); + if (fieldsDoc != null) { + caseConnectorInfo.push({ + connectorId: connectorInfo.key, + fields: fieldsDoc, + push: pushDoc, + }); + } else { + this.context.log.warn(`Unable to find fields for connector id: ${connectorInfo.key}`); } - } catch (error) { - this.log.error(`Error on creating user action of type: ${type}. Error: ${error}`); - throw error; } + + return caseConnectorInfo; + } + + private static buildConnectorInfoAggs(): Record< + string, + estypes.AggregationsAggregationContainer + > { + return { + references: { + nested: { + path: `${CASE_USER_ACTION_SAVED_OBJECT}.references`, + }, + aggregations: { + connectors: { + filter: { + term: { + [`${CASE_USER_ACTION_SAVED_OBJECT}.references.type`]: 'action', + }, + }, + aggregations: { + ids: { + // Bucket by connector id + terms: { + field: `${CASE_USER_ACTION_SAVED_OBJECT}.references.id`, + // We're assuming that a case will not have more than 1000 connectors + size: 1000, + }, + aggregations: { + reverse: { + reverse_nested: {}, + aggregations: { + connectorActivity: { + filters: { + filters: { + // look for connector fields user actions from "change connector" occurrence + changeConnector: { + term: { + [`${CASE_USER_ACTION_SAVED_OBJECT}.attributes.type`]: + ActionTypes.connector, + }, + }, + // If the case was initialized with a connector, the fields could exist in the create_case + // user action + createCase: { + term: { + [`${CASE_USER_ACTION_SAVED_OBJECT}.attributes.type`]: + ActionTypes.create_case, + }, + }, + // Also grab the most recent push occurrence for the connector + pushInfo: { + term: { + [`${CASE_USER_ACTION_SAVED_OBJECT}.attributes.type`]: + ActionTypes.pushed, + }, + }, + }, + }, + aggregations: { + mostRecent: { + top_hits: { + sort: [ + { + [`${CASE_USER_ACTION_SAVED_OBJECT}.created_at`]: { + order: 'desc', + }, + }, + ], + size: 1, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }; } public async getAll(caseId: string): Promise> { @@ -421,30 +509,34 @@ export class CaseUserActionService { const type = CASE_SAVED_OBJECT; const userActions = - await this.unsecuredSavedObjectsClient.find({ - type: CASE_USER_ACTION_SAVED_OBJECT, - hasReference: { type, id }, - page: 1, - perPage: MAX_DOCS_PER_PAGE, - sortField: 'created_at', - sortOrder: 'asc', - }); + await this.context.unsecuredSavedObjectsClient.find( + { + type: CASE_USER_ACTION_SAVED_OBJECT, + hasReference: { type, id }, + page: 1, + perPage: MAX_DOCS_PER_PAGE, + sortField: 'created_at', + sortOrder: 'asc', + } + ); return transformFindResponseToExternalModel( userActions, - this.persistableStateAttachmentTypeRegistry + this.context.persistableStateAttachmentTypeRegistry ); } catch (error) { - this.log.error(`Error on GET case user action case id: ${caseId}: ${error}`); + this.context.log.error(`Error on GET case user action case id: ${caseId}: ${error}`); throw error; } } public async getUserActionIdsForCases(caseIds: string[]) { try { - this.log.debug(`Attempting to retrieve user actions associated with cases: [${caseIds}]`); + this.context.log.debug( + `Attempting to retrieve user actions associated with cases: [${caseIds}]` + ); - const finder = this.unsecuredSavedObjectsClient.createPointInTimeFinder({ + const finder = this.context.unsecuredSavedObjectsClient.createPointInTimeFinder({ type: CASE_USER_ACTION_SAVED_OBJECT, hasReference: caseIds.map((id) => ({ id, type: CASE_SAVED_OBJECT })), sortField: 'created_at', @@ -465,78 +557,7 @@ export class CaseUserActionService { return ids; } catch (error) { - this.log.error(`Error retrieving user action ids for cases: [${caseIds}]: ${error}`); - throw error; - } - } - - private async createAndLog({ - userAction, - refresh, - }: { - userAction: UserActionEvent; - } & IndexRefresh): Promise { - const createdUserAction = await this.create({ ...userAction.parameters, refresh }); - this.auditLogger.log(userAction.eventDetails, createdUserAction.id); - } - - private async create({ - attributes, - references, - refresh, - }: CreateUserActionES): Promise> { - try { - this.log.debug(`Attempting to POST a new case user action`); - - return await this.unsecuredSavedObjectsClient.create( - CASE_USER_ACTION_SAVED_OBJECT, - attributes, - { - references: references ?? [], - refresh, - } - ); - } catch (error) { - this.log.error(`Error on POST a new case user action: ${error}`); - throw error; - } - } - - private async bulkCreateAndLog({ - userActions, - refresh, - }: { userActions: UserActionEvent[] } & IndexRefresh) { - const createdUserActions = await this.bulkCreate({ actions: userActions, refresh }); - - if (!createdUserActions) { - return; - } - - for (let i = 0; i < userActions.length; i++) { - this.auditLogger.log(userActions[i].eventDetails, createdUserActions.saved_objects[i].id); - } - } - - private async bulkCreate({ - actions, - refresh, - }: PostCaseUserActionArgs): Promise | undefined> { - if (isEmpty(actions)) { - return; - } - - try { - this.log.debug(`Attempting to POST a new case user action`); - - return await this.unsecuredSavedObjectsClient.bulkCreate( - actions.map((action) => ({ - type: CASE_USER_ACTION_SAVED_OBJECT, - ...action.parameters, - })), - { refresh } - ); - } catch (error) { - this.log.error(`Error on POST a new case user action: ${error}`); + this.context.log.error(`Error retrieving user action ids for cases: [${caseIds}]: ${error}`); throw error; } } @@ -549,7 +570,7 @@ export class CaseUserActionService { filter?: KueryNode; }): Promise>> { try { - this.log.debug('Attempting to find status changes'); + this.context.log.debug('Attempting to find status changes'); const updateActionFilter = buildFilter({ filters: Actions.update, @@ -568,7 +589,7 @@ export class CaseUserActionService { const combinedFilters = combineFilters([updateActionFilter, statusChangeFilter, filter]); const finder = - this.unsecuredSavedObjectsClient.createPointInTimeFinder( + this.context.unsecuredSavedObjectsClient.createPointInTimeFinder( { type: CASE_USER_ACTION_SAVED_OBJECT, hasReference: { type: CASE_SAVED_OBJECT, id: caseId }, @@ -583,14 +604,14 @@ export class CaseUserActionService { for await (const findResults of finder.find()) { userActions = userActions.concat( findResults.saved_objects.map((so) => - transformToExternalModel(so, this.persistableStateAttachmentTypeRegistry) + transformToExternalModel(so, this.context.persistableStateAttachmentTypeRegistry) ) ); } return userActions; } catch (error) { - this.log.error(`Error finding status changes: ${error}`); + this.context.log.error(`Error finding status changes: ${error}`); throw error; } } @@ -603,7 +624,7 @@ export class CaseUserActionService { filter?: KueryNode; }): Promise> { try { - this.log.debug(`Attempting to count connectors for case id ${caseId}`); + this.context.log.debug(`Attempting to count connectors for case id ${caseId}`); const connectorsFilter = buildFilter({ filters: [ActionTypes.connector, ActionTypes.create_case], field: 'type', @@ -613,7 +634,7 @@ export class CaseUserActionService { const combinedFilter = combineFilters([connectorsFilter, filter]); - const response = await this.unsecuredSavedObjectsClient.find< + const response = await this.context.unsecuredSavedObjectsClient.find< CaseUserActionAttributesWithoutConnectorId, { references: { connectors: { ids: { buckets: Array<{ key: string }> } } } } >({ @@ -632,7 +653,7 @@ export class CaseUserActionService { })) ?? [] ); } catch (error) { - this.log.error(`Error while counting connectors for case id ${caseId}: ${error}`); + this.context.log.error(`Error while counting connectors for case id ${caseId}: ${error}`); throw error; } } diff --git a/x-pack/plugins/cases/server/services/user_actions/operations/create.ts b/x-pack/plugins/cases/server/services/user_actions/operations/create.ts new file mode 100644 index 0000000000000..9160445ec2474 --- /dev/null +++ b/x-pack/plugins/cases/server/services/user_actions/operations/create.ts @@ -0,0 +1,433 @@ +/* + * 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 { + SavedObject, + SavedObjectReference, + SavedObjectsBulkResponse, + SavedObjectsUpdateResponse, +} from '@kbn/core/server'; +import { get, isEmpty } from 'lodash'; +import { CASE_SAVED_OBJECT, CASE_USER_ACTION_SAVED_OBJECT } from '../../../../common/constants'; +import type { CaseSavedObject } from '../../../common/types'; +import { arraysDifference } from '../../../client/utils'; +import { isUserActionType } from '../../../../common/utils/user_actions'; +import type { + ActionTypeValues, + CaseAssignees, + CaseAttributes, + CaseUserProfile, + CommentRequest, + User, + UserAction as Action, +} from '../../../../common/api'; +import { Actions, ActionTypes } from '../../../../common/api'; +import { BuilderFactory } from '../builder_factory'; +import type { + Attributes, + BuilderParameters, + CommonArguments, + CreateUserAction, + ServiceContext, + UserActionEvent, + UserActionParameters, +} from '../types'; +import { isAssigneesArray, isStringArray } from '../type_guards'; +import type { IndexRefresh } from '../../types'; +import { UserActionAuditLogger } from '../audit_logger'; + +type CommonUserActionArgs = CommonArguments; + +interface GetUserActionItemByDifference extends CommonUserActionArgs { + field: string; + originalValue: unknown; + newValue: unknown; +} + +interface TypedUserActionDiffedItems extends GetUserActionItemByDifference { + originalValue: T[]; + newValue: T[]; +} + +type CreatePayloadFunction = ( + items: Item[] +) => UserActionParameters['payload']; + +interface BulkCreateBulkUpdateCaseUserActions extends IndexRefresh { + originalCases: CaseSavedObject[]; + updatedCases: Array>; + user: User; +} + +interface BulkCreateAttachmentUserAction extends Omit, IndexRefresh { + attachments: Array<{ id: string; owner: string; attachment: CommentRequest }>; +} + +type CreateUserActionClient = CreateUserAction & + CommonUserActionArgs & + IndexRefresh; + +interface CreateUserActionES extends IndexRefresh { + attributes: T; + references: SavedObjectReference[]; +} + +interface PostCaseUserActionArgs extends IndexRefresh { + actions: UserActionEvent[]; +} + +export class UserActionPersister { + private static readonly userActionFieldsAllowed: Set = new Set(Object.keys(ActionTypes)); + + private readonly builderFactory: BuilderFactory; + private readonly auditLogger: UserActionAuditLogger; + + constructor(private readonly context: ServiceContext) { + this.builderFactory = new BuilderFactory({ + persistableStateAttachmentTypeRegistry: this.context.persistableStateAttachmentTypeRegistry, + }); + + this.auditLogger = new UserActionAuditLogger(this.context.auditLogger); + } + + public async bulkCreateUpdateCase({ + originalCases, + updatedCases, + user, + refresh, + }: BulkCreateBulkUpdateCaseUserActions): Promise { + const builtUserActions = updatedCases.reduce((acc, updatedCase) => { + const originalCase = originalCases.find(({ id }) => id === updatedCase.id); + + if (originalCase == null) { + return acc; + } + + const caseId = updatedCase.id; + const owner = originalCase.attributes.owner; + + const userActions: UserActionEvent[] = []; + const updatedFields = Object.keys(updatedCase.attributes); + + updatedFields + .filter((field) => UserActionPersister.userActionFieldsAllowed.has(field)) + .forEach((field) => { + const originalValue = get(originalCase, ['attributes', field]); + const newValue = get(updatedCase, ['attributes', field]); + userActions.push( + ...this.getUserActionItemByDifference({ + field, + originalValue, + newValue, + user, + owner, + caseId, + }) + ); + }); + + return [...acc, ...userActions]; + }, []); + + await this.bulkCreateAndLog({ + userActions: builtUserActions, + refresh, + }); + } + + private getUserActionItemByDifference(params: GetUserActionItemByDifference): UserActionEvent[] { + const { field, originalValue, newValue, caseId, owner, user } = params; + + if (!UserActionPersister.userActionFieldsAllowed.has(field)) { + return []; + } else if ( + field === ActionTypes.assignees && + isAssigneesArray(originalValue) && + isAssigneesArray(newValue) + ) { + return this.buildAssigneesUserActions({ ...params, originalValue, newValue }); + } else if ( + field === ActionTypes.tags && + isStringArray(originalValue) && + isStringArray(newValue) + ) { + return this.buildTagsUserActions({ ...params, originalValue, newValue }); + } else if (isUserActionType(field) && newValue != null) { + const userActionBuilder = this.builderFactory.getBuilder(ActionTypes[field]); + const fieldUserAction = userActionBuilder?.build({ + caseId, + owner, + user, + payload: { [field]: newValue }, + }); + + return fieldUserAction ? [fieldUserAction] : []; + } + + return []; + } + + private buildAssigneesUserActions(params: TypedUserActionDiffedItems) { + const createPayload: CreatePayloadFunction = ( + items: CaseAssignees + ) => ({ assignees: items }); + + return this.buildAddDeleteUserActions(params, createPayload, ActionTypes.assignees); + } + + private buildTagsUserActions(params: TypedUserActionDiffedItems) { + const createPayload: CreatePayloadFunction = ( + items: string[] + ) => ({ + tags: items, + }); + + return this.buildAddDeleteUserActions(params, createPayload, ActionTypes.tags); + } + + private buildAddDeleteUserActions( + params: TypedUserActionDiffedItems, + createPayload: CreatePayloadFunction, + actionType: ActionType + ) { + const { originalValue, newValue } = params; + const compareValues = arraysDifference(originalValue, newValue); + + const addUserAction = this.buildUserAction({ + commonArgs: params, + actionType, + action: Actions.add, + createPayload, + modifiedItems: compareValues?.addedItems, + }); + const deleteUserAction = this.buildUserAction({ + commonArgs: params, + actionType, + action: Actions.delete, + createPayload, + modifiedItems: compareValues?.deletedItems, + }); + + return [ + ...(addUserAction ? [addUserAction] : []), + ...(deleteUserAction ? [deleteUserAction] : []), + ]; + } + + private buildUserAction({ + commonArgs, + actionType, + action, + createPayload, + modifiedItems, + }: { + commonArgs: CommonUserActionArgs; + actionType: ActionType; + action: Action; + createPayload: CreatePayloadFunction; + modifiedItems?: Item[] | null; + }) { + const userActionBuilder = this.builderFactory.getBuilder(actionType); + + if (!userActionBuilder || !modifiedItems || modifiedItems.length <= 0) { + return; + } + + const { caseId, owner, user } = commonArgs; + + const userAction = userActionBuilder.build({ + action, + caseId, + user, + owner, + payload: createPayload(modifiedItems), + }); + + return userAction; + } + + public async bulkCreateAttachmentDeletion({ + caseId, + attachments, + user, + refresh, + }: BulkCreateAttachmentUserAction): Promise { + await this.bulkCreateAttachment({ + caseId, + attachments, + user, + action: Actions.delete, + refresh, + }); + } + + public async bulkCreateAttachmentCreation({ + caseId, + attachments, + user, + refresh, + }: BulkCreateAttachmentUserAction): Promise { + await this.bulkCreateAttachment({ + caseId, + attachments, + user, + action: Actions.create, + refresh, + }); + } + + private async bulkCreateAttachment({ + caseId, + attachments, + user, + action = Actions.create, + refresh, + }: BulkCreateAttachmentUserAction): Promise { + this.context.log.debug(`Attempting to create a bulk create case user action`); + const userActions = attachments.reduce((acc, attachment) => { + const userActionBuilder = this.builderFactory.getBuilder(ActionTypes.comment); + const commentUserAction = userActionBuilder?.build({ + action, + caseId, + user, + owner: attachment.owner, + attachmentId: attachment.id, + payload: { attachment: attachment.attachment }, + }); + + if (commentUserAction == null) { + return acc; + } + + return [...acc, commentUserAction]; + }, []); + + await this.bulkCreateAndLog({ + userActions, + refresh, + }); + } + + private async bulkCreateAndLog({ + userActions, + refresh, + }: { userActions: UserActionEvent[] } & IndexRefresh) { + const createdUserActions = await this.bulkCreate({ actions: userActions, refresh }); + + if (!createdUserActions) { + return; + } + + for (let i = 0; i < userActions.length; i++) { + this.auditLogger.log(userActions[i].eventDetails, createdUserActions.saved_objects[i].id); + } + } + + private async bulkCreate({ + actions, + refresh, + }: PostCaseUserActionArgs): Promise | undefined> { + if (isEmpty(actions)) { + return; + } + + try { + this.context.log.debug(`Attempting to POST a new case user action`); + + return await this.context.unsecuredSavedObjectsClient.bulkCreate( + actions.map((action) => ({ + type: CASE_USER_ACTION_SAVED_OBJECT, + ...action.parameters, + })), + { refresh } + ); + } catch (error) { + this.context.log.error(`Error on POST a new case user action: ${error}`); + throw error; + } + } + + public async createUserAction({ + action, + type, + caseId, + user, + owner, + payload, + connectorId, + attachmentId, + refresh, + }: CreateUserActionClient) { + try { + this.context.log.debug(`Attempting to create a user action of type: ${type}`); + const userActionBuilder = this.builderFactory.getBuilder(type); + + const userAction = userActionBuilder?.build({ + action, + caseId, + user, + owner, + connectorId, + attachmentId, + payload, + }); + + if (userAction) { + await this.createAndLog({ userAction, refresh }); + } + } catch (error) { + this.context.log.error(`Error on creating user action of type: ${type}. Error: ${error}`); + throw error; + } + } + + private async createAndLog({ + userAction, + refresh, + }: { + userAction: UserActionEvent; + } & IndexRefresh): Promise { + const createdUserAction = await this.create({ ...userAction.parameters, refresh }); + this.auditLogger.log(userAction.eventDetails, createdUserAction.id); + } + + private async create({ + attributes, + references, + refresh, + }: CreateUserActionES): Promise> { + try { + this.context.log.debug(`Attempting to POST a new case user action`); + + return await this.context.unsecuredSavedObjectsClient.create( + CASE_USER_ACTION_SAVED_OBJECT, + attributes, + { + references: references ?? [], + refresh, + } + ); + } catch (error) { + this.context.log.error(`Error on POST a new case user action: ${error}`); + throw error; + } + } + + public async bulkAuditLogCaseDeletion(caseIds: string[]) { + this.context.log.debug(`Attempting to log bulk case deletion`); + + for (const id of caseIds) { + this.auditLogger.log({ + getMessage: () => `User deleted case id: ${id}`, + action: Actions.delete, + descriptiveAction: 'case_user_action_delete_case', + savedObjectId: id, + savedObjectType: CASE_SAVED_OBJECT, + }); + } + } +} diff --git a/x-pack/plugins/cases/server/services/user_actions/types.ts b/x-pack/plugins/cases/server/services/user_actions/types.ts index be3fc602c132a..377a7217cdd02 100644 --- a/x-pack/plugins/cases/server/services/user_actions/types.ts +++ b/x-pack/plugins/cases/server/services/user_actions/types.ts @@ -5,13 +5,21 @@ * 2.0. */ -import type { SavedObjectReference } from '@kbn/core/server'; +import type { + SavedObjectReference, + SavedObjectsClientContract, + Logger, + ISavedObjectsSerializer, + SavedObject, +} from '@kbn/core/server'; +import type { AuditLogger } from '@kbn/security-plugin/server'; import type { CaseAssignees } from '../../../common/api/cases/assignee'; import type { CasePostRequest, CaseSettings, CaseSeverity, CaseStatuses, + CaseUserActionResponse, CommentUserAction, ConnectorUserAction, PushedUserAction, @@ -126,3 +134,24 @@ export type CommonBuilderArguments = CommonArguments & { export interface BuilderDeps { persistableStateAttachmentTypeRegistry: PersistableStateAttachmentTypeRegistry; } + +export interface ServiceContext { + log: Logger; + persistableStateAttachmentTypeRegistry: PersistableStateAttachmentTypeRegistry; + unsecuredSavedObjectsClient: SavedObjectsClientContract; + savedObjectsSerializer: ISavedObjectsSerializer; + auditLogger: AuditLogger; +} + +export interface CaseConnectorActivity { + connectorId: string; + fields: SavedObject; + push?: SavedObject; +} + +export type CaseConnectorFields = Map>; + +export interface PushInfo { + date: Date; + connectorId: string; +} diff --git a/x-pack/plugins/cases/tsconfig.json b/x-pack/plugins/cases/tsconfig.json index cb1039e1eff7b..bb4cc5f9e59c7 100644 --- a/x-pack/plugins/cases/tsconfig.json +++ b/x-pack/plugins/cases/tsconfig.json @@ -52,6 +52,7 @@ "@kbn/safer-lodash-set", "@kbn/logging-mocks", "@kbn/ecs", + "@kbn/core-saved-objects-base-server-mocks", ], "exclude": [ "target/**/*", diff --git a/x-pack/test/cases_api_integration/common/lib/connectors.ts b/x-pack/test/cases_api_integration/common/lib/connectors.ts new file mode 100644 index 0000000000000..4948495ddf665 --- /dev/null +++ b/x-pack/test/cases_api_integration/common/lib/connectors.ts @@ -0,0 +1,324 @@ +/* + * 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 getPort from 'get-port'; +import http from 'http'; + +import type SuperTest from 'supertest'; +import { + CASES_INTERNAL_URL, + CASE_CONFIGURE_CONNECTORS_URL, +} from '@kbn/cases-plugin/common/constants'; +import { + CasesConfigureResponse, + CaseConnector, + ConnectorTypes, + CasePostRequest, + CaseResponse, + GetCaseConnectorsResponse, +} from '@kbn/cases-plugin/common/api'; +import { ActionResult, FindActionResult } from '@kbn/actions-plugin/server/types'; +import { User } from './authentication/types'; +import { superUser } from './authentication/users'; +import { getPostCaseRequest } from './mock'; +import { ObjectRemover as ActionsRemover } from '../../../alerting_api_integration/common/lib'; +import { getServiceNowServer } from '../../../alerting_api_integration/common/plugins/actions_simulators/server/plugin'; +import { RecordingServiceNowSimulator } from '../../../alerting_api_integration/common/plugins/actions_simulators/server/servicenow_simulation'; +import { + createConfiguration, + getConfigurationRequest, + createCase, + getSpaceUrlPrefix, +} from './utils'; + +export const getResilientConnector = () => ({ + name: 'Resilient Connector', + connector_type_id: '.resilient', + secrets: { + apiKeyId: 'id', + apiKeySecret: 'secret', + }, + config: { + apiUrl: 'http://some.non.existent.com', + orgId: 'pkey', + }, +}); + +export const getWebhookConnector = () => ({ + name: 'A generic Webhook action', + connector_type_id: '.webhook', + secrets: { + user: 'user', + password: 'password', + }, + config: { + headers: { + 'Content-Type': 'text/plain', + }, + url: 'http://some.non.existent.com', + }, +}); + +export const getEmailConnector = () => ({ + name: 'An email action', + connector_type_id: '.email', + config: { + service: '__json', + from: 'bob@example.com', + }, + secrets: { + user: 'bob', + password: 'supersecret', + }, +}); + +export const getServiceNowOAuthConnector = () => ({ + name: 'ServiceNow OAuth Connector', + connector_type_id: '.servicenow', + secrets: { + clientSecret: 'xyz', + privateKey: '-----BEGIN RSA PRIVATE KEY-----\nddddddd\n-----END RSA PRIVATE KEY-----', + }, + config: { + apiUrl: 'http://some.non.existent.com', + usesTableApi: false, + isOAuth: true, + clientId: 'abc', + userIdentifierValue: 'elastic', + jwtKeyId: 'def', + }, +}); + +export const getJiraConnector = () => ({ + name: 'Jira Connector', + connector_type_id: '.jira', + secrets: { + email: 'elastic@elastic.co', + apiToken: 'token', + }, + config: { + apiUrl: 'http://some.non.existent.com', + projectKey: 'pkey', + }, +}); + +export const getCasesWebhookConnector = () => ({ + name: 'Cases Webhook Connector', + connector_type_id: '.cases-webhook', + secrets: { + user: 'user', + password: 'pass', + }, + config: { + createCommentJson: '{"body":{{{case.comment}}}}', + createCommentMethod: 'post', + createCommentUrl: 'http://some.non.existent.com/{{{external.system.id}}}/comment', + createIncidentJson: + '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', + createIncidentMethod: 'post', + createIncidentResponseKey: 'id', + createIncidentUrl: 'http://some.non.existent.com/', + getIncidentResponseExternalTitleKey: 'key', + hasAuth: true, + headers: { [`content-type`]: 'application/json' }, + viewIncidentUrl: 'http://some.non.existent.com/browse/{{{external.system.title}}}', + getIncidentUrl: 'http://some.non.existent.com/{{{external.system.id}}}', + updateIncidentJson: + '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', + updateIncidentMethod: 'put', + updateIncidentUrl: 'http://some.non.existent.com/{{{external.system.id}}}', + }, +}); + +export const getServiceNowSIRConnector = () => ({ + name: 'ServiceNow SIR Connector', + connector_type_id: '.servicenow-sir', + secrets: { + username: 'admin', + password: 'password', + }, + config: { + apiUrl: 'http://some.non.existent.com', + usesTableApi: false, + }, +}); + +export const getServiceNowConnector = () => ({ + name: 'ServiceNow Connector', + connector_type_id: '.servicenow', + secrets: { + username: 'admin', + password: 'password', + }, + config: { + apiUrl: 'http://some.non.existent.com', + usesTableApi: false, + }, +}); + +export const getRecordingServiceNowSimulatorServer = async (): Promise<{ + server: RecordingServiceNowSimulator; + url: string; +}> => { + const simulator = await RecordingServiceNowSimulator.start(); + const url = await startServiceNowSimulatorListening(simulator.server); + + return { server: simulator, url }; +}; + +const startServiceNowSimulatorListening = async (server: http.Server) => { + const port = await getPort({ port: getPort.makeRange(9000, 9100) }); + if (!server.listening) { + server.listen(port); + } + const url = `http://localhost:${port}`; + + return url; +}; + +export const getServiceNowSimulationServer = async (): Promise<{ + server: http.Server; + url: string; +}> => { + const server = await getServiceNowServer(); + const url = await startServiceNowSimulatorListening(server); + + return { server, url }; +}; + +export const getCaseConnectors = async ({ + supertest, + expectedHttpCode = 200, + auth = { user: superUser, space: null }, +}: { + supertest: SuperTest.SuperTest; + expectedHttpCode?: number; + auth?: { user: User; space: string | null }; +}): Promise => { + const { body: connectors } = await supertest + .get(`${getSpaceUrlPrefix(auth.space)}${CASE_CONFIGURE_CONNECTORS_URL}/_find`) + .auth(auth.user.username, auth.user.password) + .expect(expectedHttpCode); + + return connectors; +}; + +export const createCaseWithConnector = async ({ + supertest, + configureReq = {}, + serviceNowSimulatorURL, + actionsRemover, + auth = { user: superUser, space: null }, + createCaseReq = getPostCaseRequest(), + headers = {}, +}: { + supertest: SuperTest.SuperTest; + serviceNowSimulatorURL: string; + actionsRemover: ActionsRemover; + configureReq?: Record; + auth?: { user: User; space: string | null } | null; + createCaseReq?: CasePostRequest; + headers?: Record; +}): Promise<{ + postedCase: CaseResponse; + connector: CreateConnectorResponse; + configuration: CasesConfigureResponse; +}> => { + const connector = await createConnector({ + supertest, + req: { + ...getServiceNowConnector(), + config: { apiUrl: serviceNowSimulatorURL }, + }, + auth: auth ?? undefined, + }); + + actionsRemover.add(auth?.space ?? 'default', connector.id, 'action', 'actions'); + + const [configuration, postedCase] = await Promise.all([ + createConfiguration( + supertest, + { + ...getConfigurationRequest({ + id: connector.id, + name: connector.name, + type: connector.connector_type_id as ConnectorTypes, + }), + ...configureReq, + }, + 200, + auth ?? undefined + ), + createCase( + supertest, + { + ...createCaseReq, + connector: { + id: connector.id, + name: connector.name, + type: connector.connector_type_id, + fields: { + urgency: '2', + impact: '2', + severity: '2', + category: 'software', + subcategory: 'os', + }, + } as CaseConnector, + }, + 200, + auth, + headers + ), + ]); + + return { postedCase, connector, configuration }; +}; + +export type CreateConnectorResponse = Omit & { + connector_type_id: string; +}; + +export const createConnector = async ({ + supertest, + req, + expectedHttpCode = 200, + auth = { user: superUser, space: null }, +}: { + supertest: SuperTest.SuperTest; + req: Record; + expectedHttpCode?: number; + auth?: { user: User; space: string | null }; +}): Promise => { + const { body: connector } = await supertest + .post(`${getSpaceUrlPrefix(auth.space)}/api/actions/connector`) + .auth(auth.user.username, auth.user.password) + .set('kbn-xsrf', 'true') + .send(req) + .expect(expectedHttpCode); + + return connector; +}; + +export const getConnectors = async ({ + supertest, + caseId, + expectedHttpCode = 200, + auth = { user: superUser, space: null }, +}: { + supertest: SuperTest.SuperTest; + caseId: string; + expectedHttpCode?: number; + auth?: { user: User; space: string | null }; +}): Promise => { + const { body: connectors } = await supertest + .get(`${getSpaceUrlPrefix(auth.space)}${CASES_INTERNAL_URL}/${caseId}/_connectors`) + .auth(auth.user.username, auth.user.password) + .expect(expectedHttpCode); + + return connectors; +}; diff --git a/x-pack/test/cases_api_integration/common/lib/utils.ts b/x-pack/test/cases_api_integration/common/lib/utils.ts index 1af320a5d5c97..58dc567431546 100644 --- a/x-pack/test/cases_api_integration/common/lib/utils.ts +++ b/x-pack/test/cases_api_integration/common/lib/utils.ts @@ -6,8 +6,6 @@ */ import { omit } from 'lodash'; -import getPort from 'get-port'; -import http from 'http'; import expect from '@kbn/expect'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; @@ -19,7 +17,6 @@ import type SuperTest from 'supertest'; import { CASES_INTERNAL_URL, CASES_URL, - CASE_CONFIGURE_CONNECTORS_URL, CASE_CONFIGURE_URL, CASE_REPORTERS_URL, CASE_STATUS_URL, @@ -57,16 +54,13 @@ import { } from '@kbn/cases-plugin/common/api'; import { getCaseUserActionUrl } from '@kbn/cases-plugin/common/api/helpers'; import { SignalHit } from '@kbn/security-solution-plugin/server/lib/detection_engine/signals/types'; -import { ActionResult, FindActionResult } from '@kbn/actions-plugin/server/types'; +import { ActionResult } from '@kbn/actions-plugin/server/types'; import { ESCasesConfigureAttributes } from '@kbn/cases-plugin/server/services/configure/types'; import { ESCaseAttributes } from '@kbn/cases-plugin/server/services/cases/types'; import type { SavedObjectsRawDocSource } from '@kbn/core/server'; import { User } from './authentication/types'; import { superUser } from './authentication/users'; -import { getPostCaseRequest, postCaseReq } from './mock'; -import { ObjectRemover as ActionsRemover } from '../../../alerting_api_integration/common/lib'; -import { getServiceNowServer } from '../../../alerting_api_integration/common/plugins/actions_simulators/server/plugin'; -import { RecordingServiceNowSimulator } from '../../../alerting_api_integration/common/plugins/actions_simulators/server/servicenow_simulation'; +import { postCaseReq } from './mock'; function toArray(input: T | T[]): T[] { if (Array.isArray(input)) { @@ -209,77 +203,6 @@ export const getConfigurationOutput = ( }; }; -export const getServiceNowConnector = () => ({ - name: 'ServiceNow Connector', - connector_type_id: '.servicenow', - secrets: { - username: 'admin', - password: 'password', - }, - config: { - apiUrl: 'http://some.non.existent.com', - usesTableApi: false, - }, -}); - -export const getServiceNowOAuthConnector = () => ({ - name: 'ServiceNow OAuth Connector', - connector_type_id: '.servicenow', - secrets: { - clientSecret: 'xyz', - privateKey: '-----BEGIN RSA PRIVATE KEY-----\nddddddd\n-----END RSA PRIVATE KEY-----', - }, - config: { - apiUrl: 'http://some.non.existent.com', - usesTableApi: false, - isOAuth: true, - clientId: 'abc', - userIdentifierValue: 'elastic', - jwtKeyId: 'def', - }, -}); - -export const getJiraConnector = () => ({ - name: 'Jira Connector', - connector_type_id: '.jira', - secrets: { - email: 'elastic@elastic.co', - apiToken: 'token', - }, - config: { - apiUrl: 'http://some.non.existent.com', - projectKey: 'pkey', - }, -}); - -export const getCasesWebhookConnector = () => ({ - name: 'Cases Webhook Connector', - connector_type_id: '.cases-webhook', - secrets: { - user: 'user', - password: 'pass', - }, - config: { - createCommentJson: '{"body":{{{case.comment}}}}', - createCommentMethod: 'post', - createCommentUrl: 'http://some.non.existent.com/{{{external.system.id}}}/comment', - createIncidentJson: - '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', - createIncidentMethod: 'post', - createIncidentResponseKey: 'id', - createIncidentUrl: 'http://some.non.existent.com/', - getIncidentResponseExternalTitleKey: 'key', - hasAuth: true, - headers: { [`content-type`]: 'application/json' }, - viewIncidentUrl: 'http://some.non.existent.com/browse/{{{external.system.title}}}', - getIncidentUrl: 'http://some.non.existent.com/{{{external.system.id}}}', - updateIncidentJson: - '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', - updateIncidentMethod: 'put', - updateIncidentUrl: 'http://some.non.existent.com/{{{external.system.id}}}', - }, -}); - export const getMappings = () => [ { source: 'title', @@ -298,60 +221,6 @@ export const getMappings = () => [ }, ]; -export const getResilientConnector = () => ({ - name: 'Resilient Connector', - connector_type_id: '.resilient', - secrets: { - apiKeyId: 'id', - apiKeySecret: 'secret', - }, - config: { - apiUrl: 'http://some.non.existent.com', - orgId: 'pkey', - }, -}); - -export const getServiceNowSIRConnector = () => ({ - name: 'ServiceNow SIR Connector', - connector_type_id: '.servicenow-sir', - secrets: { - username: 'admin', - password: 'password', - }, - config: { - apiUrl: 'http://some.non.existent.com', - usesTableApi: false, - }, -}); - -export const getWebhookConnector = () => ({ - name: 'A generic Webhook action', - connector_type_id: '.webhook', - secrets: { - user: 'user', - password: 'password', - }, - config: { - headers: { - 'Content-Type': 'text/plain', - }, - url: 'http://some.non.existent.com', - }, -}); - -export const getEmailConnector = () => ({ - name: 'An email action', - connector_type_id: '.email', - config: { - service: '__json', - from: 'bob@example.com', - }, - secrets: { - user: 'bob', - password: 'supersecret', - }, -}); - interface CommonSavedObjectAttributes { id?: string | null; created_at?: string | null; @@ -589,76 +458,6 @@ export const getCaseSavedObjectsFromES = async ({ es }: { es: Client }) => { return configure; }; -export const createCaseWithConnector = async ({ - supertest, - configureReq = {}, - serviceNowSimulatorURL, - actionsRemover, - auth = { user: superUser, space: null }, - createCaseReq = getPostCaseRequest(), - headers = {}, -}: { - supertest: SuperTest.SuperTest; - serviceNowSimulatorURL: string; - actionsRemover: ActionsRemover; - configureReq?: Record; - auth?: { user: User; space: string | null } | null; - createCaseReq?: CasePostRequest; - headers?: Record; -}): Promise<{ - postedCase: CaseResponse; - connector: CreateConnectorResponse; - configuration: CasesConfigureResponse; -}> => { - const connector = await createConnector({ - supertest, - req: { - ...getServiceNowConnector(), - config: { apiUrl: serviceNowSimulatorURL }, - }, - auth: auth ?? undefined, - }); - - actionsRemover.add(auth?.space ?? 'default', connector.id, 'action', 'actions'); - const configuration = await createConfiguration( - supertest, - { - ...getConfigurationRequest({ - id: connector.id, - name: connector.name, - type: connector.connector_type_id as ConnectorTypes, - }), - ...configureReq, - }, - 200, - auth ?? undefined - ); - - const postedCase = await createCase( - supertest, - { - ...createCaseReq, - connector: { - id: connector.id, - name: connector.name, - type: connector.connector_type_id, - fields: { - urgency: '2', - impact: '2', - severity: '2', - category: 'software', - subcategory: 'os', - }, - } as CaseConnector, - }, - 200, - auth, - headers - ); - - return { postedCase, connector, configuration }; -}; - export const createCase = async ( supertest: SuperTest.SuperTest, params: CasePostRequest, @@ -979,44 +778,6 @@ export type CreateConnectorResponse = Omit & { connector_type_id: string; }; -export const createConnector = async ({ - supertest, - req, - expectedHttpCode = 200, - auth = { user: superUser, space: null }, -}: { - supertest: SuperTest.SuperTest; - req: Record; - expectedHttpCode?: number; - auth?: { user: User; space: string | null }; -}): Promise => { - const { body: connector } = await supertest - .post(`${getSpaceUrlPrefix(auth.space)}/api/actions/connector`) - .auth(auth.user.username, auth.user.password) - .set('kbn-xsrf', 'true') - .send(req) - .expect(expectedHttpCode); - - return connector; -}; - -export const getCaseConnectors = async ({ - supertest, - expectedHttpCode = 200, - auth = { user: superUser, space: null }, -}: { - supertest: SuperTest.SuperTest; - expectedHttpCode?: number; - auth?: { user: User; space: string | null }; -}): Promise => { - const { body: connectors } = await supertest - .get(`${getSpaceUrlPrefix(auth.space)}${CASE_CONFIGURE_CONNECTORS_URL}/_find`) - .auth(auth.user.username, auth.user.password) - .expect(expectedHttpCode); - - return connectors; -}; - export const updateConfiguration = async ( supertest: SuperTest.SuperTest, id: string, @@ -1265,36 +1026,6 @@ export const getAlertsAttachedToCase = async ({ return theCase; }; -export const getRecordingServiceNowSimulatorServer = async (): Promise<{ - server: RecordingServiceNowSimulator; - url: string; -}> => { - const simulator = await RecordingServiceNowSimulator.start(); - const url = await startServiceNowSimulatorListening(simulator.server); - - return { server: simulator, url }; -}; - -const startServiceNowSimulatorListening = async (server: http.Server) => { - const port = await getPort({ port: getPort.makeRange(9000, 9100) }); - if (!server.listening) { - server.listen(port); - } - const url = `http://localhost:${port}`; - - return url; -}; - -export const getServiceNowSimulationServer = async (): Promise<{ - server: http.Server; - url: string; -}> => { - const server = await getServiceNowServer(); - const url = await startServiceNowSimulatorListening(server); - - return { server, url }; -}; - /** * Extracts the warning value a warning header that is formatted according to RFC 7234. * For example for the string 299 Kibana-8.1.0 "Deprecation endpoint", the return value is Deprecation endpoint. diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/cases/push_case.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/cases/push_case.ts index a78f70710dbad..536863dc95d0a 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/cases/push_case.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/cases/push_case.ts @@ -15,13 +15,13 @@ import { deleteComments, deleteConfiguration, getConfigurationRequest, - getServiceNowConnector, - createConnector, createConfiguration, createCase, pushCase, } from '../../../../common/lib/utils'; +import { getServiceNowConnector, createConnector } from '../../../../common/lib/connectors'; + // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/configure/get_connectors.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/configure/get_connectors.ts index 57854075c20fb..f91826f431d86 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/configure/get_connectors.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/configure/get_connectors.ts @@ -8,7 +8,7 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; -import { getCaseConnectors } from '../../../../common/lib/utils'; +import { getCaseConnectors } from '../../../../common/lib/connectors'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/no_public_base_url/push.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/no_public_base_url/push.ts index fe039eed5a023..715029434324a 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/no_public_base_url/push.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/no_public_base_url/push.ts @@ -18,13 +18,11 @@ import { import { FtrProviderContext } from '../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../alerting_api_integration/common/lib'; +import { pushCase, deleteAllCaseItems, bulkCreateAttachments } from '../../../common/lib/utils'; import { - pushCase, - deleteAllCaseItems, createCaseWithConnector, getRecordingServiceNowSimulatorServer, - bulkCreateAttachments, -} from '../../../common/lib/utils'; +} from '../../../common/lib/connectors'; import { RecordingServiceNowSimulator } from '../../../../alerting_api_integration/common/plugins/actions_simulators/server/servicenow_simulation'; // eslint-disable-next-line import/no-default-export diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/push_case.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/push_case.ts index e1051a3b5de12..a50c11ff41407 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/push_case.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/push_case.ts @@ -34,20 +34,22 @@ import { updateCase, deleteAllCaseItems, superUserSpace1Auth, - createCaseWithConnector, - createConnector, - getServiceNowConnector, getConnectorMappingsFromES, getCase, - getServiceNowSimulationServer, createConfiguration, getSignalsWithES, delay, calculateDuration, - getRecordingServiceNowSimulatorServer, getComment, bulkCreateAttachments, } from '../../../../common/lib/utils'; +import { + getServiceNowConnector, + createCaseWithConnector, + getRecordingServiceNowSimulatorServer, + getServiceNowSimulationServer, + createConnector, +} from '../../../../common/lib/connectors'; import { globalRead, noKibanaPrivileges, diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/user_actions/get_all_user_actions.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/user_actions/get_all_user_actions.ts index 77ac223a07592..81a6253076d2e 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/user_actions/get_all_user_actions.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/user_actions/get_all_user_actions.ts @@ -13,17 +13,19 @@ import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { defaultUser, getPostCaseRequest } from '../../../../../common/lib/mock'; import { createCase, - createCaseWithConnector, deleteCasesByESQuery, deleteCasesUserActions, deleteComments, deleteConfiguration, getCaseUserActions, - getServiceNowSimulationServer, pushCase, updateCase, updateConfiguration, } from '../../../../../common/lib/utils'; +import { + createCaseWithConnector, + getServiceNowSimulationServer, +} from '../../../../../common/lib/connectors'; import { ObjectRemover as ActionsRemover } from '../../../../../../alerting_api_integration/common/lib'; import { setupSuperUserProfile } from '../../../../../common/lib/user_profiles'; diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_configure.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_configure.ts index 3809806d9ec11..8b29db8e0f9b6 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_configure.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_configure.ts @@ -12,15 +12,17 @@ import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; import { - getServiceNowConnector, - createConnector, createConfiguration, getConfiguration, getConfigurationRequest, removeServerGeneratedPropertiesFromSavedObject, getConfigurationOutput, - getServiceNowSimulationServer, } from '../../../../common/lib/utils'; +import { + getServiceNowConnector, + getServiceNowSimulationServer, + createConnector, +} from '../../../../common/lib/connectors'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts index 5ed6163a01543..32dc2173b4ec7 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts @@ -11,15 +11,15 @@ import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; import { getServiceNowConnector, + getServiceNowSIRConnector, getServiceNowOAuthConnector, getJiraConnector, getResilientConnector, createConnector, - getServiceNowSIRConnector, getEmailConnector, getCaseConnectors, getCasesWebhookConnector, -} from '../../../../common/lib/utils'; +} from '../../../../common/lib/connectors'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/patch_configure.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/patch_configure.ts index 6fd90d0620fd2..0bec95a51b745 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/patch_configure.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/patch_configure.ts @@ -18,10 +18,12 @@ import { deleteConfiguration, createConfiguration, updateConfiguration, +} from '../../../../common/lib/utils'; +import { getServiceNowConnector, createConnector, getServiceNowSimulationServer, -} from '../../../../common/lib/utils'; +} from '../../../../common/lib/connectors'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/post_configure.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/post_configure.ts index f9df2610dca29..561008b71bd14 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/post_configure.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/post_configure.ts @@ -17,10 +17,12 @@ import { getConfigurationOutput, deleteConfiguration, createConfiguration, - createConnector, +} from '../../../../common/lib/utils'; +import { getServiceNowConnector, getServiceNowSimulationServer, -} from '../../../../common/lib/utils'; + createConnector, +} from '../../../../common/lib/connectors'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/index.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/index.ts index becac642b1c2e..beb0c8e64045c 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/index.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/index.ts @@ -38,6 +38,7 @@ export default ({ loadTestFile, getService }: FtrProviderContext): void => { // Internal routes loadTestFile(require.resolve('./internal/suggest_user_profiles')); + loadTestFile(require.resolve('./internal/get_connectors')); // Common loadTestFile(require.resolve('../common')); diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/internal/get_connectors.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/internal/get_connectors.ts new file mode 100644 index 0000000000000..bb4d9e8b99b8c --- /dev/null +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/internal/get_connectors.ts @@ -0,0 +1,676 @@ +/* + * 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 http from 'http'; +import expect from '@kbn/expect'; + +import { ActionTypes, CaseSeverity, ConnectorTypes } from '@kbn/cases-plugin/common/api'; +import { + globalRead, + noKibanaPrivileges, + obsOnly, + obsOnlyRead, + obsSec, + obsSecRead, + secOnly, + secOnlyRead, + superUser, +} from '../../../../common/lib/authentication/users'; +import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; +import { FtrProviderContext } from '../../../../common/ftr_provider_context'; +import { + createCase, + createComment, + deleteAllCaseItems, + getCaseUserActions, + pushCase, + updateCase, +} from '../../../../common/lib/utils'; +import { getPostCaseRequest, postCommentUserReq } from '../../../../common/lib/mock'; +import { + createCaseWithConnector, + createConnector, + getConnectors, + getJiraConnector, + getServiceNowConnector, + getServiceNowSimulationServer, +} from '../../../../common/lib/connectors'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + const es = getService('es'); + const actionsRemover = new ActionsRemover(supertest); + + describe('get_connectors', () => { + let serviceNowSimulatorURL: string = ''; + let serviceNowServer: http.Server; + + before(async () => { + const { server, url } = await getServiceNowSimulationServer(); + serviceNowServer = server; + serviceNowSimulatorURL = url; + }); + + afterEach(async () => { + await deleteAllCaseItems(es); + await actionsRemover.removeAll(); + }); + + after(async () => { + serviceNowServer.close(); + }); + + it('does not return the connectors for a case that does not have connectors', async () => { + const postedCase = await createCase(supertest, getPostCaseRequest()); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + expect(Object.keys(connectors).length).to.be(0); + }); + + it('retrieves multiple connectors', async () => { + const [{ postedCase, connector: serviceNowConnector }, jiraConnector] = await Promise.all([ + createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }), + createConnector({ + supertest, + req: { + ...getJiraConnector(), + }, + }), + ]); + + actionsRemover.add('default', jiraConnector.id, 'action', 'actions'); + + const theCase = await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: serviceNowConnector.id, + }); + + await updateCase({ + supertest, + params: { + cases: [ + { + id: theCase.id, + version: theCase.version, + connector: { + id: jiraConnector.id, + name: 'Jira', + type: ConnectorTypes.jira, + fields: { issueType: 'Task', priority: null, parent: null }, + }, + }, + ], + }, + }); + + const connectors = await getConnectors({ caseId: theCase.id, supertest }); + expect(Object.keys(connectors).length).to.be(2); + expect(connectors[serviceNowConnector.id].id).to.be(serviceNowConnector.id); + expect(connectors[jiraConnector.id].id).to.be(jiraConnector.id); + }); + + describe('retrieving fields', () => { + it('retrieves a single connector using the create case user action', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + const theCase = await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: connector.id, + }); + + const connectors = await getConnectors({ caseId: theCase.id, supertest }); + const snConnector = connectors[connector.id]; + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].fields).to.eql({ + category: 'software', + impact: '2', + severity: '2', + subcategory: 'os', + urgency: '2', + }); + + expect(snConnector.needsToBePushed).to.be(false); + expect(snConnector.name).to.be('ServiceNow Connector'); + expect(snConnector.id).to.be(connector.id); + }); + + it('retrieves a single connector using the connector user action', async () => { + const postedCase = await createCase(supertest, getPostCaseRequest()); + + const jiraConnector = await createConnector({ + supertest, + req: { + ...getJiraConnector(), + }, + }); + + actionsRemover.add('default', jiraConnector.id, 'action', 'actions'); + + await updateCase({ + supertest, + params: { + cases: [ + { + id: postedCase.id, + version: postedCase.version, + connector: { + id: jiraConnector.id, + name: 'Jira', + type: ConnectorTypes.jira, + fields: { issueType: 'Task', priority: null, parent: null }, + }, + }, + ], + }, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[jiraConnector.id].id).to.be(jiraConnector.id); + }); + + it('returns the fields of the connector update after a case was created with a connector', async () => { + const { postedCase, connector: serviceNowConnector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + // change urgency to 3 + await updateCase({ + supertest, + params: { + cases: [ + { + id: postedCase.id, + version: postedCase.version, + connector: { + id: serviceNowConnector.id, + name: 'SN', + type: ConnectorTypes.serviceNowITSM, + fields: { + urgency: '3', + impact: '2', + severity: '2', + category: 'software', + subcategory: 'os', + }, + }, + }, + ], + }, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[serviceNowConnector.id].fields).to.eql({ + urgency: '3', + impact: '2', + severity: '2', + category: 'software', + subcategory: 'os', + }); + }); + }); + + describe('push', () => { + describe('latestPushDate', () => { + it('does not set latestPushDate when the connector has not been used to push', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors).to.have.property(connector.id); + expect(connectors[connector.id].latestPushDate).to.be(undefined); + }); + + it('sets latestPushDate to the most recent push date', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: connector.id, + }); + + await createComment({ + supertest, + caseId: postedCase.id, + params: postCommentUserReq, + }); + + await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: connector.id, + }); + + const [userActions, connectors] = await Promise.all([ + getCaseUserActions({ supertest, caseID: postedCase.id }), + getConnectors({ caseId: postedCase.id, supertest }), + ]); + + const pushes = userActions.filter((ua) => ua.type === ActionTypes.pushed); + const latestPush = pushes[pushes.length - 1]; + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].latestPushDate).to.eql(latestPush.created_at); + }); + }); + + describe('hasBeenPushed', () => { + it('sets hasBeenPushed to false when the connector has not been used to push', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].hasBeenPushed).to.be(false); + }); + + it('sets hasBeenPushed to true when the connector was used to push', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: connector.id, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].hasBeenPushed).to.be(true); + }); + }); + + describe('needsToBePushed', () => { + it('sets needs to push to true when a push has not occurred', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].id).to.be(connector.id); + expect(connectors[connector.id].needsToBePushed).to.be(true); + }); + + it('sets needs to push to false when a push has occurred', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: connector.id, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].id).to.be(connector.id); + expect(connectors[connector.id].needsToBePushed).to.be(false); + }); + + it('sets needs to push to true when a comment was created after the last push', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: connector.id, + }); + + await createComment({ + supertest, + caseId: postedCase.id, + params: postCommentUserReq, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].id).to.be(connector.id); + expect(connectors[connector.id].needsToBePushed).to.be(true); + }); + + it('sets needs to push to false when the severity of a case was changed after the last push', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + const pushedCase = await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: connector.id, + }); + + await updateCase({ + supertest, + params: { + cases: [ + { + id: pushedCase.id, + version: pushedCase.version, + severity: CaseSeverity.CRITICAL, + }, + ], + }, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].id).to.be(connector.id); + expect(connectors[connector.id].needsToBePushed).to.be(false); + }); + + it('sets needs to push to false the service now connector and true for jira', async () => { + const { postedCase, connector: serviceNowConnector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + const [pushedCase, jiraConnector] = await Promise.all([ + pushCase({ + supertest, + caseId: postedCase.id, + connectorId: serviceNowConnector.id, + }), + createConnector({ + supertest, + req: { + ...getJiraConnector(), + }, + }), + ]); + + actionsRemover.add('default', jiraConnector.id, 'action', 'actions'); + + await updateCase({ + supertest, + params: { + cases: [ + { + id: pushedCase.id, + version: pushedCase.version, + connector: { + id: jiraConnector.id, + name: 'Jira', + type: ConnectorTypes.jira, + fields: { issueType: 'Task', priority: null, parent: null }, + }, + }, + ], + }, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(2); + expect(connectors[serviceNowConnector.id].id).to.be(serviceNowConnector.id); + expect(connectors[serviceNowConnector.id].needsToBePushed).to.be(false); + expect(connectors[jiraConnector.id].id).to.be(jiraConnector.id); + expect(connectors[jiraConnector.id].needsToBePushed).to.be(true); + }); + + describe('changing connector fields', () => { + it('sets needs to push to false when the latest connector fields matches those used in the push', async () => { + const postedCase = await createCase(supertest, getPostCaseRequest()); + + const serviceNowConnector = await createConnector({ + supertest, + req: { + ...getServiceNowConnector(), + config: { apiUrl: serviceNowSimulatorURL }, + }, + }); + + actionsRemover.add('default', serviceNowConnector.id, 'action', 'actions'); + + const updatedCasesServiceNow = await updateCase({ + supertest, + params: { + cases: [ + { + id: postedCase.id, + version: postedCase.version, + connector: { + id: serviceNowConnector.id, + name: 'SN', + type: ConnectorTypes.serviceNowITSM, + fields: { + urgency: '2', + impact: '2', + severity: '2', + category: 'software', + subcategory: 'os', + }, + }, + }, + ], + }, + }); + + const pushedCase = await pushCase({ + supertest, + caseId: updatedCasesServiceNow[0].id, + connectorId: serviceNowConnector.id, + }); + + // switch urgency to 3 + const updatedCases = await updateCase({ + supertest, + params: { + cases: [ + { + id: pushedCase.id, + version: pushedCase.version, + connector: { + id: serviceNowConnector.id, + name: 'SN', + type: ConnectorTypes.serviceNowITSM, + fields: { + urgency: '3', + impact: '2', + severity: '2', + category: 'software', + subcategory: 'os', + }, + }, + }, + ], + }, + }); + + // switch urgency back to 2 + await updateCase({ + supertest, + params: { + cases: [ + { + id: updatedCases[0].id, + version: updatedCases[0].version, + connector: { + id: serviceNowConnector.id, + name: 'SN', + type: ConnectorTypes.serviceNowITSM, + fields: { + urgency: '2', + impact: '2', + severity: '2', + category: 'software', + subcategory: 'os', + }, + }, + }, + ], + }, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[serviceNowConnector.id].id).to.be(serviceNowConnector.id); + expect(connectors[serviceNowConnector.id].needsToBePushed).to.be(false); + }); + + it('sets needs to push to true when the latest connector fields do not match those used in the push', async () => { + const { postedCase, connector: serviceNowConnector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + const pushedCase = await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: serviceNowConnector.id, + }); + + // switch urgency to 3 + await updateCase({ + supertest, + params: { + cases: [ + { + id: pushedCase.id, + version: pushedCase.version, + connector: { + id: serviceNowConnector.id, + name: 'SN', + type: ConnectorTypes.serviceNowITSM, + fields: { + urgency: '3', + impact: '2', + severity: '2', + category: 'software', + subcategory: 'os', + }, + }, + }, + ], + }, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[serviceNowConnector.id].id).to.be(serviceNowConnector.id); + expect(connectors[serviceNowConnector.id].needsToBePushed).to.be(true); + }); + }); + }); + }); + + describe('rbac', () => { + const supertestWithoutAuth = getService('supertestWithoutAuth'); + + it('should retrieve the connectors for a case', async () => { + const { postedCase, connector: serviceNowConnector } = await createCaseWithConnector({ + supertest: supertestWithoutAuth, + serviceNowSimulatorURL, + actionsRemover, + auth: { user: superUser, space: 'space1' }, + createCaseReq: getPostCaseRequest({ owner: 'securitySolutionFixture' }), + }); + + for (const user of [globalRead, superUser, secOnly, secOnlyRead, obsSec, obsSecRead]) { + const connectors = await getConnectors({ + supertest: supertestWithoutAuth, + caseId: postedCase.id, + auth: { user, space: 'space1' }, + }); + + expect(Object.keys(connectors).length).to.eql(1); + expect(connectors[serviceNowConnector.id].id).to.eql(serviceNowConnector.id); + } + }); + + it('should not get connectors for a case when the user does not have access to the owner', async () => { + const { postedCase } = await createCaseWithConnector({ + supertest: supertestWithoutAuth, + serviceNowSimulatorURL, + actionsRemover, + auth: { user: superUser, space: 'space1' }, + createCaseReq: getPostCaseRequest({ owner: 'securitySolutionFixture' }), + }); + + for (const user of [noKibanaPrivileges, obsOnly, obsOnlyRead]) { + await getConnectors({ + supertest: supertestWithoutAuth, + caseId: postedCase.id, + expectedHttpCode: 403, + auth: { user, space: 'space1' }, + }); + } + }); + + it('should not get a case in a space the user does not have permissions to', async () => { + const { postedCase } = await createCaseWithConnector({ + supertest: supertestWithoutAuth, + serviceNowSimulatorURL, + actionsRemover, + auth: { user: superUser, space: 'space2' }, + createCaseReq: getPostCaseRequest({ owner: 'securitySolutionFixture' }), + }); + + await getConnectors({ + supertest: supertestWithoutAuth, + caseId: postedCase.id, + expectedHttpCode: 403, + auth: { user: secOnly, space: 'space2' }, + }); + }); + }); + }); +}; diff --git a/x-pack/test/cases_api_integration/spaces_only/tests/trial/cases/push_case.ts b/x-pack/test/cases_api_integration/spaces_only/tests/trial/cases/push_case.ts index 09cbc2b9ad18b..5d97cea038d5f 100644 --- a/x-pack/test/cases_api_integration/spaces_only/tests/trial/cases/push_case.ts +++ b/x-pack/test/cases_api_integration/spaces_only/tests/trial/cases/push_case.ts @@ -12,13 +12,12 @@ import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; import { nullUser } from '../../../../common/lib/mock'; +import { pushCase, deleteAllCaseItems, getAuthWithSuperUser } from '../../../../common/lib/utils'; + import { - pushCase, - deleteAllCaseItems, createCaseWithConnector, - getAuthWithSuperUser, getServiceNowSimulationServer, -} from '../../../../common/lib/utils'; +} from '../../../../common/lib/connectors'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { diff --git a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_configure.ts b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_configure.ts index c68437968e0da..025e7ba08308f 100644 --- a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_configure.ts +++ b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_configure.ts @@ -12,16 +12,18 @@ import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; import { - getServiceNowConnector, - createConnector, createConfiguration, getConfiguration, getConfigurationRequest, removeServerGeneratedPropertiesFromSavedObject, getConfigurationOutput, getAuthWithSuperUser, - getServiceNowSimulationServer, } from '../../../../common/lib/utils'; +import { + getServiceNowConnector, + createConnector, + getServiceNowSimulationServer, +} from '../../../../common/lib/connectors'; import { nullUser } from '../../../../common/lib/mock'; // eslint-disable-next-line import/no-default-export diff --git a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts index 5ec6db8bd62fb..2d5269baaf270 100644 --- a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts +++ b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts @@ -9,19 +9,18 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; +import { getAuthWithSuperUser, getActionsSpace } from '../../../../common/lib/utils'; import { getServiceNowConnector, - getServiceNowOAuthConnector, - getJiraConnector, - getResilientConnector, - createConnector, getServiceNowSIRConnector, - getAuthWithSuperUser, - getCaseConnectors, - getActionsSpace, getEmailConnector, + getCaseConnectors, getCasesWebhookConnector, -} from '../../../../common/lib/utils'; + getServiceNowOAuthConnector, + getJiraConnector, + createConnector, + getResilientConnector, +} from '../../../../common/lib/connectors'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { diff --git a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/patch_configure.ts b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/patch_configure.ts index e984cab68f9dd..54423a3195672 100644 --- a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/patch_configure.ts +++ b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/patch_configure.ts @@ -18,12 +18,14 @@ import { deleteConfiguration, createConfiguration, updateConfiguration, - getServiceNowConnector, - createConnector, getAuthWithSuperUser, getActionsSpace, - getServiceNowSimulationServer, } from '../../../../common/lib/utils'; +import { + getServiceNowConnector, + createConnector, + getServiceNowSimulationServer, +} from '../../../../common/lib/connectors'; import { nullUser } from '../../../../common/lib/mock'; // eslint-disable-next-line import/no-default-export diff --git a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/post_configure.ts b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/post_configure.ts index 4a8ffe56d35eb..97e80e790312e 100644 --- a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/post_configure.ts +++ b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/post_configure.ts @@ -17,12 +17,14 @@ import { getConfigurationOutput, deleteConfiguration, createConfiguration, - createConnector, - getServiceNowConnector, getAuthWithSuperUser, getActionsSpace, - getServiceNowSimulationServer, } from '../../../../common/lib/utils'; +import { + getServiceNowConnector, + createConnector, + getServiceNowSimulationServer, +} from '../../../../common/lib/connectors'; import { nullUser } from '../../../../common/lib/mock'; // eslint-disable-next-line import/no-default-export From d9b3a4f566e2e602dab1590425d2ef42025f9858 Mon Sep 17 00:00:00 2001 From: Philippe Oberti Date: Tue, 17 Jan 2023 14:32:08 -0600 Subject: [PATCH 16/44] [TIP] Add to blocklist functionality (#148516) --- .../public/threat_intelligence/routes.tsx | 15 +- .../cypress/e2e/block_list.cy.ts | 92 +++++++++ .../cypress/screens/indicators.ts | 16 ++ .../common/mocks/mock_security_context.tsx | 15 +- .../public/common/mocks/story_providers.tsx | 5 +- .../add_to_block_list.test.tsx.snap | 193 ++++++++++++++++++ .../add_to_block_list.stories.tsx | 37 ++++ .../add_to_block_list.test.tsx | 50 +++++ .../add_to_block_list/add_to_block_list.tsx | 62 ++++++ .../components/add_to_block_list/index.ts | 8 + .../modules/block_list/containers/flyout.tsx | 65 ++++++ .../public/modules/block_list/hooks/index.ts | 8 + .../block_list/hooks/use_set_url_params.ts | 17 ++ .../utils/can_add_to_block_list.test.ts | 50 +++++ .../block_list/utils/can_add_to_block_list.ts | 43 ++++ .../flyout/take_action/take_action.tsx | 9 + .../components/flyout/take_action/test_ids.ts | 1 + .../components/more_actions/more_actions.tsx | 14 +- .../table/components/more_actions/test_ids.ts | 1 + .../containers/block_list_provider.tsx | 25 +++ .../hooks/use_block_list_context.ts | 22 ++ .../modules/indicators/pages/indicators.tsx | 11 +- .../threat_intelligence/public/types.ts | 26 ++- .../plugins/threat_intelligence/tsconfig.json | 1 + 24 files changed, 779 insertions(+), 7 deletions(-) create mode 100644 x-pack/plugins/threat_intelligence/cypress/e2e/block_list.cy.ts create mode 100644 x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/__snapshots__/add_to_block_list.test.tsx.snap create mode 100644 x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.stories.tsx create mode 100644 x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.test.tsx create mode 100644 x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.tsx create mode 100644 x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/index.ts create mode 100644 x-pack/plugins/threat_intelligence/public/modules/block_list/containers/flyout.tsx create mode 100644 x-pack/plugins/threat_intelligence/public/modules/block_list/hooks/index.ts create mode 100644 x-pack/plugins/threat_intelligence/public/modules/block_list/hooks/use_set_url_params.ts create mode 100644 x-pack/plugins/threat_intelligence/public/modules/block_list/utils/can_add_to_block_list.test.ts create mode 100644 x-pack/plugins/threat_intelligence/public/modules/block_list/utils/can_add_to_block_list.ts create mode 100644 x-pack/plugins/threat_intelligence/public/modules/indicators/containers/block_list_provider.tsx create mode 100644 x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_block_list_context.ts diff --git a/x-pack/plugins/security_solution/public/threat_intelligence/routes.tsx b/x-pack/plugins/security_solution/public/threat_intelligence/routes.tsx index 640d90542c627..0a9c60ebfe532 100644 --- a/x-pack/plugins/security_solution/public/threat_intelligence/routes.tsx +++ b/x-pack/plugins/security_solution/public/threat_intelligence/routes.tsx @@ -12,6 +12,9 @@ import { THREAT_INTELLIGENCE_BASE_PATH } from '@kbn/threat-intelligence-plugin/p import type { SourcererDataView } from '@kbn/threat-intelligence-plugin/public/types'; import type { Store } from 'redux'; import { useSelector } from 'react-redux'; +import { useSetUrlParams } from '../management/components/artifact_list_page/hooks/use_set_url_params'; +import { BlockListForm } from '../management/pages/blocklist/view/components/blocklist_form'; +import { BlocklistsApiClient } from '../management/pages/blocklist/services'; import { useInvestigateInTimeline } from './use_investigate_in_timeline'; import { getStore, inputsSelectors } from '../common/store'; import { useKibana } from '../common/lib/kibana'; @@ -26,9 +29,10 @@ import { SiemSearchBar } from '../common/components/search_bar'; import { useGlobalTime } from '../common/containers/use_global_time'; import { deleteOneQuery, setQuery } from '../common/store/inputs/actions'; import { InputsModelId } from '../common/store/inputs/constants'; +import { ArtifactFlyout } from '../management/components/artifact_list_page/components/artifact_flyout'; const ThreatIntelligence = memo(() => { - const { threatIntelligence } = useKibana().services; + const { threatIntelligence, http } = useKibana().services; const ThreatIntelligencePlugin = threatIntelligence.getComponent(); const sourcererDataView = useSourcererDataView(); @@ -44,6 +48,15 @@ const ThreatIntelligence = memo(() => { sourcererDataView: sourcererDataView as unknown as SourcererDataView, getUseInvestigateInTimeline: useInvestigateInTimeline, + blockList: { + exceptionListApiClient: BlocklistsApiClient.getInstance(http), + useSetUrlParams, + // @ts-ignore + getFlyoutComponent: () => ArtifactFlyout, + // @ts-ignore + getFormComponent: () => BlockListForm, + }, + useQuery: () => useSelector(inputsSelectors.globalQuerySelector()), useFilters: () => useSelector(inputsSelectors.globalFiltersQuerySelector()), useGlobalTime, diff --git a/x-pack/plugins/threat_intelligence/cypress/e2e/block_list.cy.ts b/x-pack/plugins/threat_intelligence/cypress/e2e/block_list.cy.ts new file mode 100644 index 0000000000000..af3758906ea10 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/cypress/e2e/block_list.cy.ts @@ -0,0 +1,92 @@ +/* + * 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 { + BLOCK_LIST_ADD_BUTTON, + BLOCK_LIST_DESCRIPTION, + BLOCK_LIST_NAME, + BLOCK_LIST_TOAST_LIST, + FLYOUT_ADD_TO_BLOCK_LIST_ITEM, + FLYOUT_TAKE_ACTION_BUTTON, + INDICATORS_TABLE_ADD_TO_BLOCK_LIST_BUTTON_ICON, + INDICATORS_TABLE_MORE_ACTION_BUTTON_ICON, + TOGGLE_FLYOUT_BUTTON, +} from '../screens/indicators'; +import { login } from '../tasks/login'; +import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver'; +import { selectRange } from '../tasks/select_range'; + +const THREAT_INTELLIGENCE = '/app/security/threat_intelligence/indicators'; + +const BLOCK_LIST_NEW_NAME = 'new blocklist entry'; + +const fillBlocklistForm = () => { + cy.get(BLOCK_LIST_NAME).type(BLOCK_LIST_NEW_NAME); + cy.get(BLOCK_LIST_DESCRIPTION).type('the best description'); + cy.get(BLOCK_LIST_ADD_BUTTON).last().click(); + + const text: string = `"${BLOCK_LIST_NEW_NAME}" has been added`; + cy.get(BLOCK_LIST_TOAST_LIST).should('exist').and('contain.text', text); +}; + +describe('Block list with invalid indicators', () => { + before(() => { + esArchiverLoad('threat_intelligence/invalid_indicators_data'); + login(); + }); + + beforeEach(() => { + cy.visit(THREAT_INTELLIGENCE); + selectRange(); + }); + + after(() => { + esArchiverUnload('threat_intelligence/invalid_indicators_data'); + }); + + it('should disabled the indicators table context menu item if invalid indicator', () => { + cy.get(INDICATORS_TABLE_MORE_ACTION_BUTTON_ICON).eq(3).click(); + cy.get(INDICATORS_TABLE_ADD_TO_BLOCK_LIST_BUTTON_ICON).should('be.disabled'); + }); + + it('should disable the flyout context menu items if invalid indicator', () => { + cy.get(TOGGLE_FLYOUT_BUTTON).eq(3).click({ force: true }); + cy.get(FLYOUT_TAKE_ACTION_BUTTON).first().click(); + cy.get(FLYOUT_ADD_TO_BLOCK_LIST_ITEM).should('be.disabled'); + }); +}); + +describe('Block list interactions', () => { + before(() => { + esArchiverLoad('threat_intelligence/indicators_data'); + login(); + }); + + beforeEach(() => { + cy.visit(THREAT_INTELLIGENCE); + selectRange(); + }); + + after(() => { + esArchiverUnload('threat_intelligence/indicators_data'); + }); + + it('should add to block list from the indicators table', () => { + cy.get(INDICATORS_TABLE_MORE_ACTION_BUTTON_ICON).first().click(); + cy.get(INDICATORS_TABLE_ADD_TO_BLOCK_LIST_BUTTON_ICON).first().click(); + + fillBlocklistForm(); + }); + + it('should add to block list from the indicator flyout', () => { + cy.get(TOGGLE_FLYOUT_BUTTON).first().click({ force: true }); + cy.get(FLYOUT_TAKE_ACTION_BUTTON).first().click(); + cy.get(FLYOUT_ADD_TO_BLOCK_LIST_ITEM).first().click(); + + fillBlocklistForm(); + }); +}); diff --git a/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts b/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts index ac5637f5e722c..764d6348a07a8 100644 --- a/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts +++ b/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts @@ -17,6 +17,7 @@ import { } from '../../public/modules/indicators/components/barchart/legend_action/test_ids'; import { DROPDOWN_TEST_ID } from '../../public/modules/indicators/components/barchart/field_selector/test_ids'; import { + ADD_TO_BLOCK_LIST_TEST_ID as INDICATOR_FLYOUT_TAKE_ACTION_ADD_TO_BLOCK_LIST_TEST_ID, ADD_TO_EXISTING_CASE_TEST_ID as INDICATOR_FLYOUT_TAKE_ACTION_ADD_TO_EXISTING_CASE_TEST_ID, ADD_TO_NEW_CASE_TEST_ID as INDICATOR_FLYOUT_TAKE_ACTION_ADD_TO_NEW_CASE_TEST_ID, INVESTIGATE_IN_TIMELINE_TEST_ID as INDICATOR_FLYOUT_TAKE_ACTION_INVESTIGATE_IN_TIMELINE_TEST_ID, @@ -33,6 +34,7 @@ import { INDICATORS_FLYOUT_TITLE_TEST_ID, } from '../../public/modules/indicators/components/flyout/test_ids'; import { + ADD_TO_BLOCK_LIST_TEST_ID as INDICATORS_TABLE_ADD_TO_BLOCK_LIST_TEST_ID, ADD_TO_EXISTING_TEST_ID as INDICATORS_TABLE_ADD_TO_EXISTING_TEST_ID, ADD_TO_NEW_CASE_TEST_ID as INDICATORS_TABLE_ADD_TO_NEW_CASE_TEST_ID, MORE_ACTIONS_TEST_ID as INDICATORS_TABLE_MORE_ACTIONS_TEST_ID, @@ -101,6 +103,8 @@ export const INDICATORS_TABLE_ADD_TO_NEW_CASE_BUTTON_ICON = `[data-test-subj="${ export const INDICATORS_TABLE_ADD_TO_EXISTING_CASE_BUTTON_ICON = `[data-test-subj="${INDICATORS_TABLE_ADD_TO_EXISTING_TEST_ID}"]`; +export const INDICATORS_TABLE_ADD_TO_BLOCK_LIST_BUTTON_ICON = `[data-test-subj="${INDICATORS_TABLE_ADD_TO_BLOCK_LIST_TEST_ID}"]`; + /* Flyout */ export const TOGGLE_FLYOUT_BUTTON = `[data-test-subj="${BUTTON_TEST_ID}"]`; @@ -147,6 +151,8 @@ export const FLYOUT_ADD_TO_NEW_CASE_ITEM = `[data-test-subj="${INDICATOR_FLYOUT_ export const FLYOUT_INVESTIGATE_IN_TIMELINE_ITEM = `[data-test-subj="${INDICATOR_FLYOUT_TAKE_ACTION_INVESTIGATE_IN_TIMELINE_TEST_ID}"]`; +export const FLYOUT_ADD_TO_BLOCK_LIST_ITEM = `[data-test-subj="${INDICATOR_FLYOUT_TAKE_ACTION_ADD_TO_BLOCK_LIST_TEST_ID}"]`; + /* Field selector */ export const FIELD_SELECTOR = `[data-test-subj="${DROPDOWN_TEST_ID}"]`; @@ -197,6 +203,16 @@ export const NEW_CASE_DESCRIPTION_INPUT = `[data-test-subj="euiMarkdownEditorTex export const NEW_CASE_CREATE_BUTTON = `[data-test-subj="create-case-submit"]`; +/* Block list */ + +export const BLOCK_LIST_NAME = '[data-test-subj="blocklist-form-name-input"]'; + +export const BLOCK_LIST_DESCRIPTION = '[data-test-subj="blocklist-form-description-input"]'; + +export const BLOCK_LIST_ADD_BUTTON = '[class="eui-textTruncate"]'; + +export const BLOCK_LIST_TOAST_LIST = '[data-test-subj="globalToastList"]'; + /* Miscellaneous */ export const UNTITLED_TIMELINE_BUTTON = `[data-test-subj="flyoutOverlay"]`; diff --git a/x-pack/plugins/threat_intelligence/public/common/mocks/mock_security_context.tsx b/x-pack/plugins/threat_intelligence/public/common/mocks/mock_security_context.tsx index 77398772a3bb2..80cf2259ee93d 100644 --- a/x-pack/plugins/threat_intelligence/public/common/mocks/mock_security_context.tsx +++ b/x-pack/plugins/threat_intelligence/public/common/mocks/mock_security_context.tsx @@ -5,7 +5,8 @@ * 2.0. */ -import React from 'react'; +import React, { NamedExoticComponent } from 'react'; +import { BlockListFlyoutProps, BlockListFormProps } from '../../types'; import { SecuritySolutionPluginContext } from '../..'; export const getSecuritySolutionContextMock = (): SecuritySolutionPluginContext => ({ @@ -18,7 +19,10 @@ export const getSecuritySolutionContextMock = (): SecuritySolutionPluginContext ({ children }) =>
    {children}
    , licenseService: { - isEnterprise() { + isEnterprise(): boolean { + return true; + }, + isPlatinumPlus(): boolean { return true; }, }, @@ -48,4 +52,11 @@ export const getSecuritySolutionContextMock = (): SecuritySolutionPluginContext registerQuery: () => {}, deregisterQuery: () => {}, + + blockList: { + exceptionListApiClient: {}, + useSetUrlParams: () => (params, replace) => {}, + getFlyoutComponent: () => (
    ) as unknown as NamedExoticComponent, + getFormComponent: () => (
    ) as unknown as NamedExoticComponent, + }, }); diff --git a/x-pack/plugins/threat_intelligence/public/common/mocks/story_providers.tsx b/x-pack/plugins/threat_intelligence/public/common/mocks/story_providers.tsx index fbbc134a42c13..07f62805fe530 100644 --- a/x-pack/plugins/threat_intelligence/public/common/mocks/story_providers.tsx +++ b/x-pack/plugins/threat_intelligence/public/common/mocks/story_providers.tsx @@ -23,6 +23,7 @@ import { mockUiSettingsService } from './mock_kibana_ui_settings_service'; import { mockKibanaTimelinesService } from './mock_kibana_timelines_service'; import { mockTriggersActionsUiService } from './mock_kibana_triggers_actions_ui_service'; import { InspectorContext } from '../../containers/inspector'; +import { BlockListProvider } from '../../modules/indicators/containers/block_list_provider'; export interface KibanaContextMock { /** @@ -101,7 +102,9 @@ export const StoryProvidersComponent: VFC = ({ - {children} + + {children} + diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/__snapshots__/add_to_block_list.test.tsx.snap b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/__snapshots__/add_to_block_list.test.tsx.snap new file mode 100644 index 0000000000000..c8738e007c824 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/__snapshots__/add_to_block_list.test.tsx.snap @@ -0,0 +1,193 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` should render a disabled EuiContextMenuItem 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
    + +
    + , + "container":
    + +
    , + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + +exports[` should render an EuiContextMenuItem 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
    + +
    + , + "container":
    + +
    , + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.stories.tsx b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.stories.tsx new file mode 100644 index 0000000000000..437ad64d9fb99 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.stories.tsx @@ -0,0 +1,37 @@ +/* + * 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 React from 'react'; +import { Story } from '@storybook/react'; +import { EuiContextMenuPanel } from '@elastic/eui'; +import { SecuritySolutionContext } from '../../../../containers/security_solution_context'; +import { SecuritySolutionPluginContext } from '../../../..'; +import { getSecuritySolutionContextMock } from '../../../../common/mocks/mock_security_context'; +import { AddToBlockListContextMenu } from '.'; +import { BlockListProvider } from '../../../indicators/containers/block_list_provider'; + +export default { + title: 'AddToBlocklist', +}; + +export const ContextMenu: Story = () => { + const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock(); + + const mockIndicatorFileHashValue: string = 'abc'; + const mockOnClick: () => void = () => window.alert('clicked!'); + const items = [ + , + ]; + + return ( + + + + + + ); +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.test.tsx b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.test.tsx new file mode 100644 index 0000000000000..1c0c3eb448000 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.test.tsx @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render } from '@testing-library/react'; +import { AddToBlockListContextMenu } from '.'; +import { BlockListProvider } from '../../../indicators/containers/block_list_provider'; +import { SecuritySolutionContext } from '../../../../containers/security_solution_context'; +import { SecuritySolutionPluginContext } from '../../../..'; +import { getSecuritySolutionContextMock } from '../../../../common/mocks/mock_security_context'; + +describe('', () => { + it('should render an EuiContextMenuItem', () => { + const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock(); + + const mockIndicatorFileHashValue: string = 'abc'; + const mockOnClick: () => void = () => window.alert('clicked!'); + + const component = render( + + + + + + ); + + expect(component).toMatchSnapshot(); + }); + + it('should render a disabled EuiContextMenuItem', () => { + const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock(); + + const mockIndicatorFileHashValue = null; + const mockOnClick: () => void = () => window.alert('clicked!'); + + const component = render( + + + + + + ); + + expect(component).toMatchSnapshot(); + }); +}); diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.tsx b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.tsx new file mode 100644 index 0000000000000..ca74f9e5652ef --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.tsx @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { VFC } from 'react'; +import { EuiContextMenuItem } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useBlockListContext } from '../../../indicators/hooks/use_block_list_context'; +import { useSetUrlParams } from '../../hooks/use_set_url_params'; + +export interface AddToBlockListProps { + /** + * Indicator's filehash value (either sha256, sha1 or md5) + */ + data: string | null; + /** + * Used for unit and e2e tests + */ + ['data-test-subj']?: string; + /** + * Click event to notify the parent component (to for example close the popover) + */ + onClick: () => void; +} + +/** + * Add to blocklist functionality displayed as a ContextMenuItem (in the main indicators table row and in the indicator flyout). + * The entry is disabled is the filehash isn't sha256, sha1 or md5. + * When clicking on the ContextMenuItem, the indicator filehash value is saved in context. + * The flyout is shown by adding a parameter to the url. + */ +export const AddToBlockListContextMenu: VFC = ({ + data, + 'data-test-subj': dataTestSub, + onClick, +}) => { + const { setBlockListIndicatorValue } = useBlockListContext(); + const { setUrlParams } = useSetUrlParams(); + + const menuItemClicked = () => { + onClick(); + setBlockListIndicatorValue(data as string); + setUrlParams({ show: 'create' }); + }; + + return ( + menuItemClicked()} + data-test-subj={dataTestSub} + disabled={data == null} + > + + + ); +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/index.ts b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/index.ts new file mode 100644 index 0000000000000..b81a5690125d6 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/index.ts @@ -0,0 +1,8 @@ +/* + * 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 './add_to_block_list'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/containers/flyout.tsx b/x-pack/plugins/threat_intelligence/public/modules/block_list/containers/flyout.tsx new file mode 100644 index 0000000000000..b75af1add4f41 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/containers/flyout.tsx @@ -0,0 +1,65 @@ +/* + * 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 React, { VFC } from 'react'; +import { + CreateExceptionListItemSchema, + EntriesArray, +} from '@kbn/securitysolution-io-ts-list-types'; +import { useSecurityContext } from '../../../hooks/use_security_context'; + +export interface BlockListFlyoutProps { + /** + * Indicator file-hash value (sha256, sh1 or md5) to pass to the block list flyout. + */ + indicatorFileHash: string; +} + +/** + * Component calling the block list flyout (retrieved from the SecuritySolution plugin via context). + * This reuses a lot of components passed down via context from the Security Solution plugin: + * - the flyout component: https://github.com/elastic/kibana/blob/main/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.tsx + * - the form component: https://github.com/elastic/kibana/blob/main/x-pack/plugins/security_solution/public/management/pages/blocklist/view/components/blocklist_form.tsx + */ +export const BlockListFlyout: VFC = ({ indicatorFileHash }) => { + const { blockList } = useSecurityContext(); + const Component = blockList.getFlyoutComponent(); + const exceptionListApiClient = blockList.exceptionListApiClient; + const FormComponent = blockList.getFormComponent(); + + // prepopulate the for with the indicator file hash + const entries: EntriesArray = [ + { + field: 'file.hash.*', + operator: 'included', + type: 'match_any', + value: [indicatorFileHash], + }, + ]; + + // prepare the payload to pass to the form (and then sent to the blocklist endpoint) + const item: CreateExceptionListItemSchema = { + description: '', + entries, + list_id: 'endpoint_blocklists', + name: '', + namespace_type: 'agnostic', + os_types: ['windows'], + tags: ['policy:all'], + type: 'simple', + }; + + const props = { + apiClient: exceptionListApiClient, + item, + policies: [], + FormComponent, + onClose: () => {}, + }; + + return ; +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/hooks/index.ts b/x-pack/plugins/threat_intelligence/public/modules/block_list/hooks/index.ts new file mode 100644 index 0000000000000..491a1968d7974 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/hooks/index.ts @@ -0,0 +1,8 @@ +/* + * 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 './use_set_url_params'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/hooks/use_set_url_params.ts b/x-pack/plugins/threat_intelligence/public/modules/block_list/hooks/use_set_url_params.ts new file mode 100644 index 0000000000000..20f8312267c2b --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/hooks/use_set_url_params.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useSecurityContext } from '../../../hooks'; + +/** + * Retrieve the useSetUrlParams hook from SecurityContext. + * The hook is passed down from the Security Solution plugin. + */ +export const useSetUrlParams = () => { + const { blockList } = useSecurityContext(); + return { setUrlParams: blockList.useSetUrlParams() }; +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/utils/can_add_to_block_list.test.ts b/x-pack/plugins/threat_intelligence/public/modules/block_list/utils/can_add_to_block_list.test.ts new file mode 100644 index 0000000000000..35b8d479b681d --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/utils/can_add_to_block_list.test.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + generateMockFileIndicator, + Indicator, + RawIndicatorFieldId, +} from '../../../../common/types/indicator'; +import { canAddToBlockList } from './can_add_to_block_list'; +import { getIndicatorFieldAndValue } from '../../indicators'; + +describe('canAddToBlockList', () => { + it('should return null if indicator has none of required fields', () => { + const indicator = {} as unknown as Indicator; + const result = canAddToBlockList(indicator); + + expect(result).toEqual(null); + }); + + it('should return sha256 value if indicator has the field', () => { + const indicator = generateMockFileIndicator(); + const sha256 = getIndicatorFieldAndValue(indicator, RawIndicatorFieldId.FileSha256).value; + const result = canAddToBlockList(indicator); + + expect(result).toEqual(sha256); + }); + + it('should return sha1 value if sha256 is missing ', () => { + const indicator = generateMockFileIndicator(); + indicator.fields['threat.indicator.file.hash.sha256'] = undefined; + const sha1 = getIndicatorFieldAndValue(indicator, RawIndicatorFieldId.FileSha1).value; + const result = canAddToBlockList(indicator); + + expect(result).toEqual(sha1); + }); + + it('should return md5 value if sha256 and sha1 are missing', () => { + const indicator = generateMockFileIndicator(); + indicator.fields['threat.indicator.file.hash.sha256'] = undefined; + indicator.fields['threat.indicator.file.hash.sha1'] = undefined; + const md5 = getIndicatorFieldAndValue(indicator, RawIndicatorFieldId.FileMd5).value; + const result = canAddToBlockList(indicator); + + expect(result).toEqual(md5); + }); +}); diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/utils/can_add_to_block_list.ts b/x-pack/plugins/threat_intelligence/public/modules/block_list/utils/can_add_to_block_list.ts new file mode 100644 index 0000000000000..037a4f4587e0f --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/utils/can_add_to_block_list.ts @@ -0,0 +1,43 @@ +/* + * 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 { Indicator, RawIndicatorFieldId } from '../../../../common/types/indicator'; +import { getIndicatorFieldAndValue } from '../../indicators'; + +/** + * Checks if an indicator has sha256, sha1 or md5 (in that order) and returns an empty string if it does not. + * The value is returned to be used in the add to block list logic. + * + * @param indicator the indicator we want to + */ +export const canAddToBlockList = (indicator: Indicator): string | null => { + const sha256: string | null = getIndicatorFieldAndValue( + indicator, + RawIndicatorFieldId.FileSha256 + ).value; + if (sha256 != null) { + return sha256; + } + + const sha1: string | null = getIndicatorFieldAndValue( + indicator, + RawIndicatorFieldId.FileSha1 + ).value; + if (sha1 != null) { + return sha1; + } + + const md5: string | null = getIndicatorFieldAndValue( + indicator, + RawIndicatorFieldId.FileMd5 + ).value; + if (md5 != null) { + return md5; + } + + return null; +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/take_action.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/take_action.tsx index 8a67d596c1333..93c5890b23396 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/take_action.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/take_action.tsx @@ -8,11 +8,14 @@ import React, { useState, VFC } from 'react'; import { EuiButton, EuiContextMenuPanel, EuiPopover, useGeneratedHtmlId } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import { canAddToBlockList } from '../../../../block_list/utils/can_add_to_block_list'; +import { AddToBlockListContextMenu } from '../../../../block_list/components/add_to_block_list'; import { AddToNewCase } from '../../../../cases/components/add_to_new_case/add_to_new_case'; import { AddToExistingCase } from '../../../../cases/components/add_to_existing_case/add_to_existing_case'; import { Indicator } from '../../../../../../common/types/indicator'; import { InvestigateInTimelineContextMenu } from '../../../../timeline'; import { + ADD_TO_BLOCK_LIST_TEST_ID, ADD_TO_EXISTING_CASE_TEST_ID, ADD_TO_NEW_CASE_TEST_ID, INVESTIGATE_IN_TIMELINE_TEST_ID, @@ -39,6 +42,7 @@ export const TakeAction: VFC = ({ indicator }) => { setPopover(false); }; + const indicatorValue: string | null = canAddToBlockList(indicator); const items = [ = ({ indicator }) => { onClick={closePopover} data-test-subj={ADD_TO_NEW_CASE_TEST_ID} />, + , ]; const button = ( diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/test_ids.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/test_ids.ts index 051a9637a9f6c..f661ae2357171 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/test_ids.ts +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/test_ids.ts @@ -9,3 +9,4 @@ export const TAKE_ACTION_BUTTON_TEST_ID = 'tiIndicatorFlyoutTakeActionButton'; export const INVESTIGATE_IN_TIMELINE_TEST_ID = 'tiIndicatorFlyoutInvestigateInTimelineContextMenu'; export const ADD_TO_EXISTING_CASE_TEST_ID = 'tiIndicatorFlyoutAddToExistingCaseContextMenu'; export const ADD_TO_NEW_CASE_TEST_ID = 'tiIndicatorFlyoutAddToNewCaseContextMenu'; +export const ADD_TO_BLOCK_LIST_TEST_ID = 'tiIndicatorFlyoutAddToBlockListContextMenu'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/more_actions.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/more_actions.tsx index 705b9c5090f6c..a5f6955f00004 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/more_actions.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/more_actions.tsx @@ -14,10 +14,17 @@ import { useGeneratedHtmlId, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { AddToBlockListContextMenu } from '../../../../../block_list/components/add_to_block_list'; import { AddToNewCase } from '../../../../../cases/components/add_to_new_case/add_to_new_case'; import { AddToExistingCase } from '../../../../../cases/components/add_to_existing_case/add_to_existing_case'; import { Indicator } from '../../../../../../../common/types/indicator'; -import { ADD_TO_EXISTING_TEST_ID, ADD_TO_NEW_CASE_TEST_ID, MORE_ACTIONS_TEST_ID } from './test_ids'; +import { canAddToBlockList } from '../../../../../block_list/utils/can_add_to_block_list'; +import { + ADD_TO_BLOCK_LIST_TEST_ID, + ADD_TO_EXISTING_TEST_ID, + ADD_TO_NEW_CASE_TEST_ID, + MORE_ACTIONS_TEST_ID, +} from './test_ids'; const BUTTON_LABEL = i18n.translate('xpack.threatIntelligence.indicator.table.moreActions', { defaultMessage: 'More actions', @@ -55,6 +62,11 @@ export const MoreActions: VFC = ({ indicator }) => { onClick={closePopover} data-test-subj={ADD_TO_NEW_CASE_TEST_ID} />, + , ]; const button = ( diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/test_ids.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/test_ids.ts index 7e5666283b218..37edc59e11e8b 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/test_ids.ts +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/test_ids.ts @@ -8,3 +8,4 @@ export const MORE_ACTIONS_TEST_ID = 'tiIndicatorTableMoreActionsButton'; export const ADD_TO_EXISTING_TEST_ID = 'tiIndicatorTableAddToExistingCaseContextMenu'; export const ADD_TO_NEW_CASE_TEST_ID = 'tiIndicatorTableAddToNewCaseContextMenu'; +export const ADD_TO_BLOCK_LIST_TEST_ID = 'tiIndicatorsTableAddToBlockListContextMenu'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/block_list_provider.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/block_list_provider.tsx new file mode 100644 index 0000000000000..3bdd3be858af7 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/block_list_provider.tsx @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { createContext, Dispatch, FC, SetStateAction, useState } from 'react'; + +export interface BlockListContextValue { + blockListIndicatorValue: string; + setBlockListIndicatorValue: Dispatch>; +} + +export const BlockListContext = createContext(undefined); + +export const BlockListProvider: FC = ({ children }) => { + const [blockListIndicatorValue, setBlockListIndicatorValue] = useState(''); + + const context: BlockListContextValue = { + blockListIndicatorValue, + setBlockListIndicatorValue, + }; + return {children}; +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_block_list_context.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_block_list_context.ts new file mode 100644 index 0000000000000..7aad9bd41745a --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_block_list_context.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. + */ + +import { useContext } from 'react'; +import { BlockListContext, BlockListContextValue } from '../containers/block_list_provider'; + +/** + * Hook to retrieve {@link BlockListContext} + */ +export const useBlockListContext = (): BlockListContextValue => { + const contextValue = useContext(BlockListContext); + + if (!contextValue) { + throw new Error('BlockListContext can only be used within BlockListContext provider'); + } + + return contextValue; +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx index aaac18f3fb215..005538fe383e9 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx @@ -6,6 +6,9 @@ */ import React, { FC, VFC } from 'react'; +import { useBlockListContext } from '../hooks/use_block_list_context'; +import { BlockListProvider } from '../containers/block_list_provider'; +import { BlockListFlyout } from '../../block_list/containers/flyout'; import { IndicatorsBarChartWrapper } from '../components/barchart'; import { IndicatorsTable } from '../components/table'; import { useAggregatedIndicators, useIndicators, useSourcererDataView } from '../hooks'; @@ -22,12 +25,16 @@ import { QueryBar } from '../../query_bar/query_bar'; const IndicatorsPageProviders: FC = ({ children }) => ( - {children} + + {children} + ); const IndicatorsPageContent: VFC = () => { + const { blockListIndicatorValue } = useBlockListContext(); + const { browserFields, indexPattern } = useSourcererDataView(); const columnSettings = useColumnSettings(); @@ -101,6 +108,8 @@ const IndicatorsPageContent: VFC = () => { onChangeItemsPerPage={onChangeItemsPerPage} onChangePage={onChangePage} /> + + {blockListIndicatorValue && } ); diff --git a/x-pack/plugins/threat_intelligence/public/types.ts b/x-pack/plugins/threat_intelligence/public/types.ts index 9b11c705a20d0..73051c0f0e285 100644 --- a/x-pack/plugins/threat_intelligence/public/types.ts +++ b/x-pack/plugins/threat_intelligence/public/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { ComponentType, ReactElement, ReactNode, VFC } from 'react'; +import { ComponentType, NamedExoticComponent, ReactElement, ReactNode, VFC } from 'react'; import { CoreStart } from '@kbn/core/public'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { @@ -22,6 +22,7 @@ import { Store } from 'redux'; import { DataProvider } from '@kbn/timelines-plugin/common'; import { Start as InspectorPluginStart } from '@kbn/inspector-plugin/public'; import { CasesUiSetup, CasesUiStart } from '@kbn/cases-plugin/public/types'; +import { CreateExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; export interface SecuritySolutionDataViewBase extends DataViewBase { fields: Array; @@ -57,6 +58,7 @@ export type Services = { export interface LicenseAware { isEnterprise(): boolean; + isPlatinumPlus(): boolean; } export type BrowserFields = Readonly>>; @@ -74,6 +76,18 @@ export interface UseInvestigateInTimelineProps { to: string; } +export interface BlockListFlyoutProps { + apiClient: unknown; + item: CreateExceptionListItemSchema; + policies: unknown[]; + FormComponent: NamedExoticComponent; + onClose: () => void; +} + +export interface BlockListFormProps { + item: CreateExceptionListItemSchema; +} + /** * Methods exposed from the security solution to the threat intelligence application. */ @@ -124,4 +138,14 @@ export interface SecuritySolutionPluginContext { * Deregister stale query */ deregisterQuery: (query: { id: string }) => void; + + blockList: { + exceptionListApiClient: unknown; + useSetUrlParams: () => ( + params: Record, + replace?: boolean | undefined + ) => void; + getFlyoutComponent: () => NamedExoticComponent; + getFormComponent: () => NamedExoticComponent; + }; } diff --git a/x-pack/plugins/threat_intelligence/tsconfig.json b/x-pack/plugins/threat_intelligence/tsconfig.json index a8e1b2a96b37d..3006da321be78 100644 --- a/x-pack/plugins/threat_intelligence/tsconfig.json +++ b/x-pack/plugins/threat_intelligence/tsconfig.json @@ -31,6 +31,7 @@ "@kbn/kibana-react-plugin", "@kbn/utility-types", "@kbn/ui-theme", + "@kbn/securitysolution-io-ts-list-types" ], "exclude": [ "target/**/*", From 8233211960febfa4bb15d13d783d306fc3a1efb0 Mon Sep 17 00:00:00 2001 From: Jon Date: Tue, 17 Jan 2023 15:40:38 -0600 Subject: [PATCH 17/44] [ci] Fix storybooks (#149077) There's a [known issue](https://github.com/storybookjs/storybook/issues/20482) with storybooks 6 and node 18+ requiring use of the legacy openssl provider. This adds the `--openssl-legacy-provider` flag to our storybooks entrypoint. This is similar to a few of the webpack related changes in https://github.com/elastic/kibana/pull/144012, merging early to fix CI. FYI @watson --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 98171db69f469..4a9a7336ef711 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "makelogs": "node scripts/makelogs", "spec_to_console": "node scripts/spec_to_console", "start": "node scripts/kibana --dev", - "storybook": "node scripts/storybook", + "storybook": "node --openssl-legacy-provider scripts/storybook", "test:ftr": "node scripts/functional_tests", "test:ftr:runner": "node scripts/functional_test_runner", "test:ftr:server": "node scripts/functional_tests_server", From 83a1904491cefdbe2e6873fed311d51326755eae Mon Sep 17 00:00:00 2001 From: Garrett Spong Date: Tue, 17 Jan 2023 15:02:57 -0700 Subject: [PATCH 18/44] [Security Solution] Adds support for testing of prerelease detection rules (#148426) ## Summary Resolves https://github.com/elastic/kibana/issues/147466 Resolves https://github.com/elastic/kibana/issues/112910 * Updates `useUpgradeSecurityPackages` hook to install the `prerelease` version of the `endpoint` and `security_detection_engine` packages if the current branch is `main` or build is `-SNAPSHOT` (to ensure PR's are testing against the latest to-be-released packages) * Adds new `kibana.yml` configuration `xpack.securitySolution.prebuiltRulesPackageVersion` for specifying the version of the `security_detection_engine` package to install within the client-side logic of the `useUpgradeSecurityPackages` hook * Adds FTR helpers for consuming the `xpack.securitySolution.prebuiltRulesPackageVersion` configuration from the `kbnServerArgs` and for installing a specific detection rules package version [c467762](https://github.com/elastic/kibana/pull/148426/commits/c467762386f8ba919f34b294df4f7661995addba). * Regenerated docs * Unskips `useUpgradeSecurityPackages` tests from [#112910](https://github.com/elastic/kibana/issues/112910) Note: I added jest tests for the `useUpgradeSecurityPackages` changes, however didn't find a reasonable way to test the `prebuiltRulesPackageVersion` configuration addition via FTR's, so ended up testing that manually by running a local `package-registry` and serving up two different versions of the `security_detection_engine` package (`8.3.1`/`8.4.1`) and specifying > xpack.securitySolution.prebuiltRulesPackageVersion: '8.3.1' in my `kibana.dev.yml` to try and install the previous version. This initially failed as fleet would say the package is `out-of-date`

    Since there was a higher version with the same `kibana.version` requirement: `kibana.version: ^8.4.0`. Modifying this for the higher version to `^8.9.0` then allowed for the installation of the `8.3.1` as specified in the `prebuiltRulesPackageVersion` setting:

    As [mentioned](https://github.com/elastic/kibana/pull/148426#issuecomment-1380249233) by @xcrzx, I ended up adding `force:true` to the individual install request to get around this limitation and to have a better testing experience within Cypress. Note II: When using the `prebuiltRulesPackageVersion` setting, since this is used for updates initiated from the client and not on kibana start like the `fleet_package.json` (added in https://github.com/elastic/kibana/pull/143839), you will have to uninstall the package that was installed on start-up for this to be successful. Note III: When wanting to run the Cypress tests against a specific package version, be sure to update the cypress FTR configuration [cf3a83f](https://github.com/elastic/kibana/pull/148426/commits/cf3a83f773e3773015d80e0d102826bde4b94f70). ### Checklist Delete any items that are not applicable to this PR. - [X] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [X] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- api_docs/security_solution.devdocs.json | 35 +++++- api_docs/security_solution.mdx | 2 +- .../resources/base/bin/kibana-docker | 1 + .../test_suites/core_plugins/rendering.ts | 1 + .../use_upgrade_secuirty_packages.test.tsx | 110 +++++++++++++++++- .../hooks/use_upgrade_security_packages.ts | 63 ++++++++-- .../common/lib/kibana/__mocks__/index.ts | 2 + .../public/common/lib/kibana/services.ts | 33 ++++-- .../mock/endpoint/app_context_render.tsx | 1 + .../security_solution/public/common/types.ts | 1 + .../security_solution/public/plugin.tsx | 29 ++++- .../security_solution/server/config.mock.ts | 1 + .../security_solution/server/config.ts | 13 +++ .../plugins/security_solution/server/index.ts | 1 + ...tall_detection_rules_package_from_fleet.ts | 61 ++++++++++ .../test/security_solution_cypress/config.ts | 2 + 16 files changed, 330 insertions(+), 26 deletions(-) create mode 100644 x-pack/test/detection_engine_api_integration/utils/install_detection_rules_package_from_fleet.ts diff --git a/api_docs/security_solution.devdocs.json b/api_docs/security_solution.devdocs.json index 8e51ac05f833a..5c8d70432251e 100644 --- a/api_docs/security_solution.devdocs.json +++ b/api_docs/security_solution.devdocs.json @@ -45,13 +45,44 @@ "deprecated": false, "trackAdoption": false, "children": [ + { + "parentPluginId": "securitySolution", + "id": "def-public.Plugin.kibanaBranch", + "type": "string", + "tags": [], + "label": "kibanaBranch", + "description": [ + "\nThe current Kibana branch. e.g. 'main'" + ], + "path": "x-pack/plugins/security_solution/public/plugin.tsx", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "securitySolution", "id": "def-public.Plugin.kibanaVersion", "type": "string", "tags": [], "label": "kibanaVersion", - "description": [], + "description": [ + "\nThe current Kibana version. e.g. '8.0.0' or '8.0.0-SNAPSHOT'" + ], + "path": "x-pack/plugins/security_solution/public/plugin.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.Plugin.prebuiltRulesPackageVersion", + "type": "string", + "tags": [], + "label": "prebuiltRulesPackageVersion", + "description": [ + "\nFor internal use. Specify which version of the Detection Rules fleet package to install\nwhen upgrading rules. If not provided, the latest compatible package will be installed,\nor if running from a dev environment or -SNAPSHOT build, the latest pre-release package\nwill be used (if fleet is available or not within an airgapped environment).\n\nNote: This is for `upgrade only`, which occurs by means of the `useUpgradeSecurityPackages`\nhook when navigating to a Security Solution page. The package version specified in\n`fleet_packages.json` in project root will always be installed first on Kibana start if\nthe package is not already installed." + ], + "signature": [ + "string | undefined" + ], "path": "x-pack/plugins/security_solution/public/plugin.tsx", "deprecated": false, "trackAdoption": false @@ -2007,7 +2038,7 @@ "label": "ConfigType", "description": [], "signature": [ - "Readonly<{} & { signalsIndex: string; maxRuleImportExportSize: number; maxRuleImportPayloadBytes: number; maxTimelineImportExportSize: number; maxTimelineImportPayloadBytes: number; alertMergeStrategy: \"allFields\" | \"missingFields\" | \"noFields\"; alertIgnoreFields: string[]; enableExperimental: string[]; packagerTaskInterval: string; }> & { experimentalFeatures: ", + "Readonly<{ prebuiltRulesPackageVersion?: string | undefined; } & { signalsIndex: string; maxRuleImportExportSize: number; maxRuleImportPayloadBytes: number; maxTimelineImportExportSize: number; maxTimelineImportPayloadBytes: number; alertMergeStrategy: \"allFields\" | \"missingFields\" | \"noFields\"; alertIgnoreFields: string[]; enableExperimental: string[]; packagerTaskInterval: string; }> & { experimentalFeatures: ", "ExperimentalFeatures", "; }" ], diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index fb9d774afca33..3dd7644fcda20 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -21,7 +21,7 @@ Contact [Security solution](https://github.com/orgs/elastic/teams/security-solut | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 113 | 0 | 76 | 29 | +| 115 | 0 | 75 | 29 | ## Client diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker index c7262af593189..9c5f2511f1617 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker @@ -394,6 +394,7 @@ kibana_vars=( xpack.securitySolution.maxTimelineImportExportSize xpack.securitySolution.maxTimelineImportPayloadBytes xpack.securitySolution.packagerTaskInterval + xpack.securitySolution.prebuiltRulesPackageVersion xpack.spaces.maxSpaces xpack.task_manager.max_attempts xpack.task_manager.max_poll_inactivity_cycles diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index 5c51d00f5afd1..a13d19e5246eb 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -218,6 +218,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'xpack.security.sameSiteCookies (alternatives)', 'xpack.security.showInsecureClusterWarning (boolean)', 'xpack.securitySolution.enableExperimental (array)', + 'xpack.securitySolution.prebuiltRulesPackageVersion (string)', 'xpack.snapshot_restore.slm_ui.enabled (boolean)', 'xpack.snapshot_restore.ui.enabled (boolean)', 'xpack.trigger_actions_ui.enableExperimental (array)', diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx b/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx index f40f1dd0fecc0..0352dd03bbcff 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx +++ b/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx @@ -6,7 +6,7 @@ */ import React, { memo } from 'react'; -import { useKibana } from '../lib/kibana'; +import { KibanaServices, useKibana } from '../lib/kibana'; import type { RenderHookResult } from '@testing-library/react-hooks'; import { renderHook as _renderHook } from '@testing-library/react-hooks'; import { useUpgradeSecurityPackages } from './use_upgrade_security_packages'; @@ -23,8 +23,11 @@ jest.mock('../components/user_privileges', () => { }); jest.mock('../lib/kibana'); -// FLAKY: https://github.com/elastic/kibana/issues/112910 -describe.skip('When using the `useUpgradeSecurityPackages()` hook', () => { +describe('When using the `useUpgradeSecurityPackages()` hook', () => { + const mockGetPrebuiltRulesPackageVersion = + KibanaServices.getPrebuiltRulesPackageVersion as jest.Mock; + const mockGetKibanaVersion = KibanaServices.getKibanaVersion as jest.Mock; + const mockGetKibanaBranch = KibanaServices.getKibanaBranch as jest.Mock; let renderResult: RenderHookResult; let renderHook: () => RenderHookResult; let kibana: ReturnType; @@ -43,6 +46,7 @@ describe.skip('When using the `useUpgradeSecurityPackages()` hook', () => { }); afterEach(() => { + jest.clearAllMocks(); if (renderResult) { renderResult.unmount(); } @@ -65,4 +69,104 @@ describe.skip('When using the `useUpgradeSecurityPackages()` hook', () => { }) ); }); + + it('should send upgrade request with prerelease:false if branch is not `main` and build does not include `-SNAPSHOT`', async () => { + mockGetKibanaVersion.mockReturnValue('8.0.0'); + mockGetKibanaBranch.mockReturnValue('release'); + + renderHook(); + + await renderResult.waitFor( + () => (kibana.services.http.post as jest.Mock).mock.calls.length > 0 + ); + + expect(kibana.services.http.post).toHaveBeenCalledWith( + `${epmRouteService.getBulkInstallPath()}`, + expect.objectContaining({ + body: '{"packages":["endpoint","security_detection_engine"]}', + query: expect.objectContaining({ prerelease: false }), + }) + ); + }); + + it('should send upgrade request with prerelease:true if branch is `main` AND build includes `-SNAPSHOT`', async () => { + mockGetKibanaVersion.mockReturnValue('8.0.0-SNAPSHOT'); + mockGetKibanaBranch.mockReturnValue('main'); + + renderHook(); + + await renderResult.waitFor( + () => (kibana.services.http.post as jest.Mock).mock.calls.length > 0 + ); + + expect(kibana.services.http.post).toHaveBeenCalledWith( + `${epmRouteService.getBulkInstallPath()}`, + expect.objectContaining({ + body: '{"packages":["endpoint","security_detection_engine"]}', + query: expect.objectContaining({ prerelease: true }), + }) + ); + }); + + it('should send upgrade request with prerelease:true if branch is `release` and build includes `-SNAPSHOT`', async () => { + mockGetKibanaVersion.mockReturnValue('8.0.0-SNAPSHOT'); + mockGetKibanaBranch.mockReturnValue('release'); + + renderHook(); + + await renderResult.waitFor( + () => (kibana.services.http.post as jest.Mock).mock.calls.length > 0 + ); + + expect(kibana.services.http.post).toHaveBeenCalledWith( + `${epmRouteService.getBulkInstallPath()}`, + expect.objectContaining({ + body: '{"packages":["endpoint","security_detection_engine"]}', + query: expect.objectContaining({ prerelease: true }), + }) + ); + }); + + it('should send upgrade request with prerelease:true if branch is `main` and build does not include `-SNAPSHOT`', async () => { + mockGetKibanaVersion.mockReturnValue('8.0.0'); + mockGetKibanaBranch.mockReturnValue('main'); + + renderHook(); + + await renderResult.waitFor( + () => (kibana.services.http.post as jest.Mock).mock.calls.length > 0 + ); + + expect(kibana.services.http.post).toHaveBeenCalledWith( + `${epmRouteService.getBulkInstallPath()}`, + expect.objectContaining({ + body: '{"packages":["endpoint","security_detection_engine"]}', + query: expect.objectContaining({ prerelease: true }), + }) + ); + }); + + it('should send separate upgrade requests if prebuiltRulesPackageVersion is provided', async () => { + mockGetPrebuiltRulesPackageVersion.mockReturnValue('8.2.1'); + + renderHook(); + + await renderResult.waitFor( + () => (kibana.services.http.post as jest.Mock).mock.calls.length > 0 + ); + + expect(kibana.services.http.post).toHaveBeenNthCalledWith( + 1, + `${epmRouteService.getInstallPath('security_detection_engine', '8.2.1')}`, + expect.objectContaining({ query: { prerelease: true } }) + ); + expect(kibana.services.http.post).toHaveBeenNthCalledWith( + 2, + `${epmRouteService.getBulkInstallPath()}`, + expect.objectContaining({ + body: expect.stringContaining('endpoint'), + query: expect.objectContaining({ prerelease: true }), + }) + ); + }); }); diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_security_packages.ts b/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_security_packages.ts index 848f1458502ca..1354770b7384d 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_security_packages.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_security_packages.ts @@ -9,7 +9,8 @@ import { useEffect } from 'react'; import type { HttpFetchOptions, HttpStart } from '@kbn/core/public'; import type { BulkInstallPackagesResponse } from '@kbn/fleet-plugin/common'; import { epmRouteService } from '@kbn/fleet-plugin/common'; -import { useKibana } from '../lib/kibana'; +import type { InstallPackageResponse } from '@kbn/fleet-plugin/common/types'; +import { KibanaServices, useKibana } from '../lib/kibana'; import { useUserPrivileges } from '../components/user_privileges'; /** @@ -17,17 +18,44 @@ import { useUserPrivileges } from '../components/user_privileges'; * * @param http an http client for sending the request * @param options an object containing options for the request + * @param prebuiltRulesPackageVersion specific version of the prebuilt rules package to install */ const sendUpgradeSecurityPackages = async ( http: HttpStart, - options: HttpFetchOptions = {} -): Promise => { - return http.post(epmRouteService.getBulkInstallPath(), { - ...options, - body: JSON.stringify({ - packages: ['endpoint', 'security_detection_engine'], - }), - }); + options: HttpFetchOptions = {}, + prebuiltRulesPackageVersion?: string +): Promise => { + const packages = ['endpoint', 'security_detection_engine']; + const requests: Array> = []; + + // If `prebuiltRulesPackageVersion` is provided, try to install that version + // Must be done as two separate requests as bulk API doesn't support versions + if (prebuiltRulesPackageVersion != null) { + packages.splice(packages.indexOf('security_detection_engine'), 1); + requests.push( + http.post( + epmRouteService.getInstallPath('security_detection_engine', prebuiltRulesPackageVersion), + { + ...options, + body: JSON.stringify({ + force: true, + }), + } + ) + ); + } + + // Note: if `prerelease:true` option is provided, endpoint package will also be installed as prerelease + requests.push( + http.post(epmRouteService.getBulkInstallPath(), { + ...options, + body: JSON.stringify({ + packages, + }), + }) + ); + + await Promise.allSettled(requests); }; export const useUpgradeSecurityPackages = () => { @@ -50,8 +78,23 @@ export const useUpgradeSecurityPackages = () => { // Make sure fleet is initialized first await context.services.fleet?.isInitialized(); + // Always install the latest package if in dev env or snapshot build + const isPrerelease = + KibanaServices.getKibanaVersion().includes('-SNAPSHOT') || + KibanaServices.getKibanaBranch() === 'main'; + // ignore the response for now since we aren't notifying the user - await sendUpgradeSecurityPackages(context.services.http, { signal }); + // Note: response would be Promise.allSettled, so must iterate all responses for errors and throw manually + await sendUpgradeSecurityPackages( + context.services.http, + { + query: { + prerelease: isPrerelease, + }, + signal, + }, + KibanaServices.getPrebuiltRulesPackageVersion() + ); } catch (error) { // Ignore Errors, since this should not hinder the user's ability to use the UI diff --git a/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts b/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts index 6b736e3fbb503..2822a48669b32 100644 --- a/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts @@ -36,6 +36,8 @@ export const KibanaServices = { }; }), getKibanaVersion: jest.fn(() => '8.0.0'), + getKibanaBranch: jest.fn(() => 'main'), + getPrebuiltRulesPackageVersion: jest.fn(() => undefined), }; export const useKibana = jest.fn().mockReturnValue({ services: { diff --git a/x-pack/plugins/security_solution/public/common/lib/kibana/services.ts b/x-pack/plugins/security_solution/public/common/lib/kibana/services.ts index 7b38c7e2a4218..cbd2ddce441ae 100644 --- a/x-pack/plugins/security_solution/public/common/lib/kibana/services.ts +++ b/x-pack/plugins/security_solution/public/common/lib/kibana/services.ts @@ -12,7 +12,9 @@ type GlobalServices = Pick; export class KibanaServices { + private static kibanaBranch?: string; private static kibanaVersion?: string; + private static prebuiltRulesPackageVersion?: string; private static services?: GlobalServices; public static init({ @@ -20,19 +22,20 @@ export class KibanaServices { application, data, unifiedSearch, + kibanaBranch, kibanaVersion, + prebuiltRulesPackageVersion, uiSettings, notifications, - }: GlobalServices & { kibanaVersion: string }) { - this.services = { - application, - data, - http, - uiSettings, - unifiedSearch, - notifications, - }; + }: GlobalServices & { + kibanaBranch: string; + kibanaVersion: string; + prebuiltRulesPackageVersion?: string; + }) { + this.services = { application, data, http, uiSettings, unifiedSearch, notifications }; + this.kibanaBranch = kibanaBranch; this.kibanaVersion = kibanaVersion; + this.prebuiltRulesPackageVersion = prebuiltRulesPackageVersion; } public static get(): GlobalServices { @@ -43,6 +46,14 @@ export class KibanaServices { return this.services; } + public static getKibanaBranch(): string { + if (!this.kibanaBranch) { + this.throwUninitializedError(); + } + + return this.kibanaBranch; + } + public static getKibanaVersion(): string { if (!this.kibanaVersion) { this.throwUninitializedError(); @@ -51,6 +62,10 @@ export class KibanaServices { return this.kibanaVersion; } + public static getPrebuiltRulesPackageVersion(): string | undefined { + return this.prebuiltRulesPackageVersion; + } + private static throwUninitializedError(): never { throw new Error( 'Kibana services not initialized - are you trying to import this module from outside of the SIEM app?' diff --git a/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx b/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx index 2e2cdbdd3eda5..5a9d092ad5097 100644 --- a/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx +++ b/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx @@ -292,6 +292,7 @@ export const createAppRootMockRenderer = (): AppContextTestRender => { const globalKibanaServicesParams = { ...startServices, kibanaVersion: '8.0.0', + kibanaBranch: 'main', }; if (jest.isMockFunction(KibanaServices.get)) { diff --git a/x-pack/plugins/security_solution/public/common/types.ts b/x-pack/plugins/security_solution/public/common/types.ts index 8eced13424255..c639975e499a0 100644 --- a/x-pack/plugins/security_solution/public/common/types.ts +++ b/x-pack/plugins/security_solution/public/common/types.ts @@ -18,6 +18,7 @@ export interface ServerApiError { export interface SecuritySolutionUiConfigType { enableExperimental: string[]; + prebuiltRulesPackageVersion?: string; } /** diff --git a/x-pack/plugins/security_solution/public/plugin.tsx b/x-pack/plugins/security_solution/public/plugin.tsx index 3e08672939b5c..b7b4fcb051d65 100644 --- a/x-pack/plugins/security_solution/public/plugin.tsx +++ b/x-pack/plugins/security_solution/public/plugin.tsx @@ -61,7 +61,26 @@ import { LazyEndpointCustomAssetsExtension } from './management/pages/policy/vie import type { SecurityAppStore } from './common/store/types'; export class Plugin implements IPlugin { + /** + * The current Kibana branch. e.g. 'main' + */ + readonly kibanaBranch: string; + /** + * The current Kibana version. e.g. '8.0.0' or '8.0.0-SNAPSHOT' + */ readonly kibanaVersion: string; + /** + * For internal use. Specify which version of the Detection Rules fleet package to install + * when upgrading rules. If not provided, the latest compatible package will be installed, + * or if running from a dev environment or -SNAPSHOT build, the latest pre-release package + * will be used (if fleet is available or not within an airgapped environment). + * + * Note: This is for `upgrade only`, which occurs by means of the `useUpgradeSecurityPackages` + * hook when navigating to a Security Solution page. The package version specified in + * `fleet_packages.json` in project root will always be installed first on Kibana start if + * the package is not already installed. + */ + readonly prebuiltRulesPackageVersion?: string; private config: SecuritySolutionUiConfigType; readonly experimentalFeatures: ExperimentalFeatures; @@ -69,6 +88,8 @@ export class Plugin implements IPlugin(); this.experimentalFeatures = parseExperimentalConfigValue(this.config.enableExperimental || []); this.kibanaVersion = initializerContext.env.packageInfo.version; + this.kibanaBranch = initializerContext.env.packageInfo.branch; + this.prebuiltRulesPackageVersion = this.config.prebuiltRulesPackageVersion; } private appUpdater$ = new Subject(); @@ -214,7 +235,13 @@ export class Plugin implements IPlugin { maxTimelineImportPayloadBytes: 10485760, enableExperimental, packagerTaskInterval: '60s', + prebuiltRulesPackageVersion: '', alertMergeStrategy: 'missingFields', alertIgnoreFields: [], diff --git a/x-pack/plugins/security_solution/server/config.ts b/x-pack/plugins/security_solution/server/config.ts index 08683436505e3..5a4d18edda11c 100644 --- a/x-pack/plugins/security_solution/server/config.ts +++ b/x-pack/plugins/security_solution/server/config.ts @@ -109,6 +109,19 @@ export const configSchema = schema.object({ * Artifacts Configuration */ packagerTaskInterval: schema.string({ defaultValue: '60s' }), + + /** + * For internal use. Specify which version of the Detection Rules fleet package to install + * when upgrading rules. If not provided, the latest compatible package will be installed, + * or if running from a dev environment or -SNAPSHOT build, the latest pre-release package + * will be used (if fleet is available or not within an airgapped environment). + * + * Note: This is for `upgrade only`, which occurs by means of the `useUpgradeSecurityPackages` + * hook when navigating to a Security Solution page. The package version specified in + * `fleet_packages.json` in project root will always be installed first on Kibana start if + * the package is not already installed. + */ + prebuiltRulesPackageVersion: schema.maybe(schema.string()), }); export type ConfigSchema = TypeOf; diff --git a/x-pack/plugins/security_solution/server/index.ts b/x-pack/plugins/security_solution/server/index.ts index e167f62afd1e7..cc59610f21124 100644 --- a/x-pack/plugins/security_solution/server/index.ts +++ b/x-pack/plugins/security_solution/server/index.ts @@ -20,6 +20,7 @@ export const plugin = (context: PluginInitializerContext) => { export const config: PluginConfigDescriptor = { exposeToBrowser: { enableExperimental: true, + prebuiltRulesPackageVersion: true, }, schema: configSchema, deprecations: ({ renameFromRoot, unused }) => [ diff --git a/x-pack/test/detection_engine_api_integration/utils/install_detection_rules_package_from_fleet.ts b/x-pack/test/detection_engine_api_integration/utils/install_detection_rules_package_from_fleet.ts new file mode 100644 index 0000000000000..72408d8fd2af1 --- /dev/null +++ b/x-pack/test/detection_engine_api_integration/utils/install_detection_rules_package_from_fleet.ts @@ -0,0 +1,61 @@ +/* + * 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 { epmRouteService } from '@kbn/fleet-plugin/common'; +import { InstallPackageResponse } from '@kbn/fleet-plugin/common/types'; +import type { ToolingLog } from '@kbn/tooling-log'; +import type SuperTest from 'supertest'; + +/** + * Installed the security_detection_engine package via fleet API. Will + * @param supertest The supertest deps + * @param log The tooling logger + * @param version The version to install, e.g. '8.4.1' + * @param overrideExistingPackage Whether or not to force the install + */ +export const installDetectionRulesPackageFromFleet = async ( + supertest: SuperTest.SuperTest, + log: ToolingLog, + version: string, + overrideExistingPackage: true +): Promise => { + const response = await supertest + .post(epmRouteService.getInstallPath('security_detection_engine', version)) + .set('kbn-xsrf', 'true') + .send({ + force: overrideExistingPackage, + }); + if (response.status !== 200) { + log.error( + `Did not get an expected 200 "ok" when installing 'security_detection_engine' fleet package'. body: ${JSON.stringify( + response.body + )}, status: ${JSON.stringify(response.status)}` + ); + } + return response.body; +}; + +/** + * Returns the `--xpack.securitySolution.prebuiltRulesPackageVersion=8.3.1` setting + * as configured in the kbnServerArgs from the test's config.ts. + * @param kbnServerArgs Kibana server args within scope + */ +export const getPrebuiltRulesPackageVersionFromServerArgs = (kbnServerArgs: string[]): string => { + const re = + /--xpack\.securitySolution\.prebuiltRulesPackageVersion=(?.*)/; + for (const serverArg of kbnServerArgs) { + const match = re.exec(serverArg); + const prebuiltRulesPackageVersion = match?.groups?.prebuiltRulesPackageVersion; + if (prebuiltRulesPackageVersion) { + return prebuiltRulesPackageVersion; + } + } + + throw Error( + 'xpack.securitySolution.prebuiltRulesPackageVersion is not set in the server arguments' + ); +}; diff --git a/x-pack/test/security_solution_cypress/config.ts b/x-pack/test/security_solution_cypress/config.ts index 81d18ce1cab5d..c8048c0b1ba4b 100644 --- a/x-pack/test/security_solution_cypress/config.ts +++ b/x-pack/test/security_solution_cypress/config.ts @@ -52,6 +52,8 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { // mock cloud to enable the guided onboarding tour in e2e tests '--xpack.cloud.id=test', `--home.disableWelcomeScreen=true`, + // Specify which version of the detection-rules package to install + // `--xpack.securitySolution.prebuiltRulesPackageVersion=8.3.1`, ], }, }; From 28ba652c3d36ef12cd47521a5b801b829db175c1 Mon Sep 17 00:00:00 2001 From: Candace Park <56409205+parkiino@users.noreply.github.com> Date: Tue, 17 Jan 2023 14:25:19 -0800 Subject: [PATCH 19/44] [Security][Features] Adds subtext option to Kibana feature and sub-feature controls (#147709) ## Summary - [x] Allow plugins to configure a description subtext underneath kibana features - [x] Allow plugins to configure a description subtext underneath kibana subfeatures - [x] Adjusts subfeature form UI so privilege buttons have fullwidth, adjusts padding/margins - [x] Adds unit tests # Screen Shots image Privilege button group before ![image](https://user-images.githubusercontent.com/56409205/208610978-557d1881-f222-4a29-9ae3-d60baf34e1ac.png) Privilege button group after image Example to test: 1. In `x-pack/plugins/security_solution/server/features.ts` before `privilegeGroups` on line 254, add `description: 'some subfeature description here'` and before `management` on line 551, add `description: 'some feature description here'`. 3. Stack Management > Roles > edit Kibana Privileges > Security > Security see descriptions show up underneath Security and underneath Endpoint List sub feature --- .../plugins/features/common/kibana_feature.ts | 9 ++ x-pack/plugins/features/common/sub_feature.ts | 9 ++ .../plugins/features/server/feature_schema.ts | 2 + .../roles/__fixtures__/kibana_features.ts | 2 +- .../kibana/feature_table/feature_table.scss | 16 +- .../feature_table/feature_table.test.tsx | 153 ++++++++++++++++++ .../kibana/feature_table/feature_table.tsx | 22 +-- .../feature_table_expanded_row.tsx | 2 +- .../kibana/feature_table/sub_feature_form.tsx | 30 +++- .../feature_table_cell.scss | 3 + .../feature_table_cell.test.tsx | 4 +- .../feature_table_cell/feature_table_cell.tsx | 32 +++- .../roles/model/secured_sub_feature.ts | 4 + 13 files changed, 257 insertions(+), 31 deletions(-) create mode 100644 x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.scss diff --git a/x-pack/plugins/features/common/kibana_feature.ts b/x-pack/plugins/features/common/kibana_feature.ts index 2989872d024c9..debcec588dee0 100644 --- a/x-pack/plugins/features/common/kibana_feature.ts +++ b/x-pack/plugins/features/common/kibana_feature.ts @@ -32,6 +32,11 @@ export interface KibanaFeatureConfig { */ name: string; + /** + * An optional description that will appear as subtext underneath the feature name + */ + description?: string; + /** * The category for this feature. * This will be used to organize the list of features for display within the @@ -156,6 +161,10 @@ export class KibanaFeature { return this.config.name; } + public get description() { + return this.config.description; + } + public get order() { return this.config.order; } diff --git a/x-pack/plugins/features/common/sub_feature.ts b/x-pack/plugins/features/common/sub_feature.ts index 58142fd88c0c3..e51fc42195797 100644 --- a/x-pack/plugins/features/common/sub_feature.ts +++ b/x-pack/plugins/features/common/sub_feature.ts @@ -29,6 +29,11 @@ export interface SubFeatureConfig { /** Collection of privilege groups */ privilegeGroups: readonly SubFeaturePrivilegeGroupConfig[]; + + /** + * An optional description that will appear as subtext underneath the sub-feature name + */ + description?: string; } /** @@ -105,6 +110,10 @@ export class SubFeature { return this.config.requireAllSpaces ?? false; } + public get description() { + return this.config.description || ''; + } + public toRaw() { return { ...this.config }; } diff --git a/x-pack/plugins/features/server/feature_schema.ts b/x-pack/plugins/features/server/feature_schema.ts index 05d172887d870..cfc7c2ee47eaa 100644 --- a/x-pack/plugins/features/server/feature_schema.ts +++ b/x-pack/plugins/features/server/feature_schema.ts @@ -165,6 +165,7 @@ const kibanaSubFeatureSchema = schema.object({ name: schema.string(), requireAllSpaces: schema.maybe(schema.boolean()), privilegesTooltip: schema.maybe(schema.string()), + description: schema.maybe(schema.string()), privilegeGroups: schema.maybe( schema.arrayOf( schema.oneOf([ @@ -198,6 +199,7 @@ const kibanaFeatureSchema = schema.object({ }), name: schema.string(), category: appCategorySchema, + description: schema.maybe(schema.string()), order: schema.maybe(schema.number()), excludeFromBasePrivileges: schema.maybe(schema.boolean()), minimumLicense: schema.maybe(validLicenseSchema), diff --git a/x-pack/plugins/security/public/management/roles/__fixtures__/kibana_features.ts b/x-pack/plugins/security/public/management/roles/__fixtures__/kibana_features.ts index f33b8659fb27f..b69e09aa7bff7 100644 --- a/x-pack/plugins/security/public/management/roles/__fixtures__/kibana_features.ts +++ b/x-pack/plugins/security/public/management/roles/__fixtures__/kibana_features.ts @@ -11,7 +11,7 @@ import { KibanaFeature } from '@kbn/features-plugin/public'; export const createFeature = ( config: Pick< KibanaFeatureConfig, - 'id' | 'name' | 'subFeatures' | 'reserved' | 'privilegesTooltip' + 'id' | 'name' | 'subFeatures' | 'reserved' | 'privilegesTooltip' | 'description' > & { excludeFromBaseAll?: boolean; excludeFromBaseRead?: boolean; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.scss b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.scss index e5c026d317034..f03a4582598ee 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.scss +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.scss @@ -1,5 +1,11 @@ -.subFeaturePrivilegeExpandedRegion { - background-color: $euiColorLightestShade; - padding-left: $euiSizeXXL; - padding-top: $euiSizeS; -} \ No newline at end of file +.euiAccordionWithDescription:hover, .euiAccordionWithDescription:focus { + text-decoration: none; +} + +.subFeaturePanel { + margin-left: $euiSizeL + $euiSizeXS; +} + +.noSubFeaturePrivileges { + margin-left: $euiSizeL + $euiSizeXS; +} diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.test.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.test.tsx index 7f5ac97e41edf..0383e857adda4 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.test.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.test.tsx @@ -837,6 +837,63 @@ describe('FeatureTable', () => { expect(findTestSubject(wrapper, 'primaryFeaturePrivilegeControl')).toHaveLength(0); }); + it('renders subtext for features that define an optional description', () => { + const role = createRole([ + { + spaces: ['foo'], + base: [], + feature: { + my_feature: ['all'], + }, + }, + ]); + const featureWithDescription = createFeature({ + id: 'my_feature', + name: 'Some Feature', + description: 'a description of my feature', + }); + + const { wrapper } = setup({ + role, + features: [featureWithDescription], + privilegeIndex: 0, + calculateDisplayedPrivileges: false, + canCustomizeSubFeaturePrivileges: false, + }); + + expect(findTestSubject(wrapper, 'featurePrivilegeDescriptionText').exists()).toEqual(true); + + expect( + findTestSubject(wrapper, 'featurePrivilegeDescriptionText').text() + ).toMatchInlineSnapshot(`"a description of my feature"`); + }); + + it('does not render subtext for features without a description', () => { + const role = createRole([ + { + spaces: ['foo'], + base: [], + feature: { + my_feature: ['all'], + }, + }, + ]); + const featureWithDescription = createFeature({ + id: 'my_feature', + name: 'Some Feature', + }); + + const { wrapper } = setup({ + role, + features: [featureWithDescription], + privilegeIndex: 0, + calculateDisplayedPrivileges: false, + canCustomizeSubFeaturePrivileges: false, + }); + + expect(findTestSubject(wrapper, 'featurePrivilegeDescriptionText').exists()).toEqual(false); + }); + it('renders renders the primary feature controls when both primary and reserved privileges are specified', () => { const role = createRole([ { @@ -1315,4 +1372,100 @@ describe('FeatureTable', () => { expect(type).toBe('empty'); }); }); + describe('Optional description for sub-features', () => { + const role = createRole([ + { + spaces: ['foo'], + base: [], + feature: { + unit_test: ['minimal_read', 'sub-toggle-1', 'sub-toggle-2'], + }, + }, + ]); + + it('renders description subtext if defined', () => { + const feature = createFeature({ + id: 'unit_test', + name: 'Unit Test Feature', + subFeatures: [ + { + name: 'Some Sub Feature', + description: 'some sub feature description', + privilegeGroups: [ + { + groupType: 'independent', + privileges: [ + { + id: 'sub-toggle-1', + name: 'Sub Toggle 1', + includeIn: 'all', + savedObject: { all: [], read: [] }, + ui: ['sub-toggle-1'], + }, + ], + }, + ], + }, + ] as SubFeatureConfig[], + }); + const { wrapper } = setup({ + role, + features: [feature], + privilegeIndex: 0, + calculateDisplayedPrivileges: false, + canCustomizeSubFeaturePrivileges: true, + }); + + const categoryExpander = findTestSubject(wrapper, 'featureCategoryButton_foo'); + categoryExpander.simulate('click'); + + const featureExpander = findTestSubject(wrapper, 'featureTableCell'); + featureExpander.simulate('click'); + + expect(findTestSubject(wrapper, 'subFeatureDescription').exists()).toEqual(true); + expect(findTestSubject(wrapper, 'subFeatureDescription').text()).toMatchInlineSnapshot( + `"some sub feature description"` + ); + }); + it('should not render description subtext if undefined', () => { + const feature = createFeature({ + id: 'unit_test', + name: 'Unit Test Feature', + subFeatures: [ + { + name: 'Some Sub Feature', + privilegeGroups: [ + { + groupType: 'independent', + privileges: [ + { + id: 'sub-toggle-1', + name: 'Sub Toggle 1', + includeIn: 'all', + savedObject: { all: [], read: [] }, + ui: ['sub-toggle-1'], + }, + ], + }, + ], + }, + ] as SubFeatureConfig[], + }); + const { wrapper } = setup({ + role, + features: [feature], + privilegeIndex: 0, + calculateDisplayedPrivileges: false, + canCustomizeSubFeaturePrivileges: true, + }); + + const categoryExpander = findTestSubject(wrapper, 'featureCategoryButton_foo'); + categoryExpander.simulate('click'); + + const featureExpander = findTestSubject(wrapper, 'featureTableCell'); + featureExpander.simulate('click'); + + expect(findTestSubject(wrapper, 'subFeatureDescription').exists()).toEqual(false); + }); + }); }); diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.tsx index 33f9f2879b4f7..d2a5625b724a6 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.tsx @@ -17,10 +17,12 @@ import { EuiHorizontalRule, EuiIcon, EuiIconTip, + EuiPanel, EuiSpacer, EuiText, EuiTitle, } from '@elastic/eui'; +import classNames from 'classnames'; import type { ReactElement } from 'react'; import React, { Component } from 'react'; @@ -221,11 +223,12 @@ export class FeatureTable extends Component { return ( {infoIcon} - + { }); }} > -
    + + { this.props.canCustomizeSubFeaturePrivileges } /> -
    +
    @@ -267,9 +271,7 @@ export class FeatureTable extends Component { if (feature.reserved && primaryFeaturePrivileges.length === 0) { const buttonContent = ( - <> - {} - + ); const extraAction = ( @@ -336,10 +338,10 @@ export class FeatureTable extends Component { const hasSubFeaturePrivileges = feature.getSubFeaturePrivileges().length > 0; const buttonContent = ( - <> - {!hasSubFeaturePrivileges && }{' '} - - + ); const extraAction = ( diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table_expanded_row.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table_expanded_row.tsx index e5e28c4547374..e89102e62ca8d 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table_expanded_row.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table_expanded_row.tsx @@ -70,7 +70,7 @@ export const FeatureTableExpandedRow = ({ }; return ( - +
    { if (groupsWithPrivileges.length === 0) { return null; } - return ( - - - - {props.subFeature.name} {getTooltip()} - + + + + + + {props.subFeature.name} {getTooltip()} + + + {props.subFeature.description && ( + + + {props.subFeature.description} + + + )} + - {groupsWithPrivileges.map(renderPrivilegeGroup)} + {groupsWithPrivileges.map(renderPrivilegeGroup)} ); @@ -157,6 +172,7 @@ export const SubFeatureForm = (props: Props) => { key={index} buttonSize="compressed" data-test-subj="mutexSubFeaturePrivilegeControl" + isFullWidth options={options} idSelected={firstSelectedPrivilege?.id ?? NO_PRIVILEGE_VALUE} isDisabled={props.disabled} diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.scss b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.scss new file mode 100644 index 0000000000000..8a002996b67ed --- /dev/null +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.scss @@ -0,0 +1,3 @@ +.featurePrivilegeName:hover, .featurePrivilegeName:focus { + text-decoration: underline; +} diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.test.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.test.tsx index 006ae053940d8..c503ef35ae06c 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.test.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.test.tsx @@ -25,7 +25,7 @@ describe('FeatureTableCell', () => { ); - expect(wrapper.text()).toMatchInlineSnapshot(`"Test Feature "`); + expect(wrapper.text()).toMatchInlineSnapshot(`"Test Feature"`); expect(wrapper.find(EuiIconTip)).toHaveLength(0); }); @@ -40,7 +40,7 @@ describe('FeatureTableCell', () => { ); - expect(wrapper.text()).toMatchInlineSnapshot(`"Test Feature Info"`); + expect(wrapper.text()).toMatchInlineSnapshot(`"Test FeatureInfo"`); expect(wrapper.find(EuiIconTip).props().content).toMatchInlineSnapshot(` diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.tsx index 507416b51f9b6..062597ce46ad2 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.tsx @@ -5,16 +5,19 @@ * 2.0. */ -import { EuiIconTip, EuiText } from '@elastic/eui'; +import './feature_table_cell.scss'; + +import { EuiFlexGroup, EuiFlexItem, EuiIconTip, EuiText } from '@elastic/eui'; import React from 'react'; import type { SecuredFeature } from '../../../../model'; interface Props { feature: SecuredFeature; + className?: string; } -export const FeatureTableCell = ({ feature }: Props) => { +export const FeatureTableCell = ({ feature, className }: Props) => { let tooltipElement = null; if (feature.getPrivilegesTooltip()) { const tooltipContent = ( @@ -35,8 +38,27 @@ export const FeatureTableCell = ({ feature }: Props) => { } return ( - - {feature.name} {tooltipElement} - + + + + + {feature.name} + + {tooltipElement} + + + {feature.description && ( + + + {feature.description} + + + )} + ); }; diff --git a/x-pack/plugins/security/public/management/roles/model/secured_sub_feature.ts b/x-pack/plugins/security/public/management/roles/model/secured_sub_feature.ts index 8c312ee7ea772..79e98625cb06f 100644 --- a/x-pack/plugins/security/public/management/roles/model/secured_sub_feature.ts +++ b/x-pack/plugins/security/public/management/roles/model/secured_sub_feature.ts @@ -44,4 +44,8 @@ export class SecuredSubFeature extends SubFeature { .filter((privilege) => predicate(privilege, this)); } } + + public getDescription() { + return this.description; + } } From a0ac890f23f2e1f54ac4f57ca4085e21950b8202 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Wed, 18 Jan 2023 00:19:56 +0000 Subject: [PATCH 20/44] [Fleet] Add default `inactivity_timeout` value of 2 weeks to all new agent policies (#149031) ## Summary Closes #148527 All new agent policies should default inactivity timeout to 2 weeks (1209600 seconds). ### Test cases - When installing a package for the first time in cloud, the 'My first agent policy' agent policy should have inactivity timeout set to `1209600`. This can be tested locally by adding `?useMultiPageLayout` to the add integration URL e.g: `/app/fleet/integrations/system-1.20.4/add-integration?useMultiPageLayout` - When adding an integration (non multi page layout e.g `/app/fleet/integrations/system-1.20.4/add-integration`) and electing to create a new agent policy, under 'advanced' inactivity timeout should be pre-populated with 1209600: Screenshot 2023-01-17 at 12 22 59 - When creating a new agent policy from the agent policy screen, under "advanced options", inactivity timeout should be pre-populated with 1209600: Screenshot 2023-01-17 at 12 25 20 - (covered by integration test also) When creating a new agent policy via the API, if no inactivity timeout is specified it should default to 1209600: ``` POST kbn:/api/fleet/agent_policies { "name": "Default inactivity timeout", "description": "", "namespace": "default", "monitoring_enabled": [ "logs", "metrics" ] } ``` --- .../components/agent_policy_create_inline.tsx | 16 ++++---- .../hooks/use_get_agent_policy_or_default.tsx | 18 +++++---- .../single_page_layout/index.test.tsx | 2 + .../single_page_layout/index.tsx | 11 ++---- .../components/create_agent_policy.tsx | 15 ++++--- .../generate_new_agent_policy.test.ts | 39 +++++++++++++++++++ .../services/generate_new_agent_policy.ts | 26 +++++++++++++ x-pack/plugins/fleet/public/services/index.ts | 1 + .../fleet/server/types/models/agent_policy.ts | 4 +- .../apis/agent_policy/agent_policy.ts | 3 ++ .../apis/fleet_telemetry.ts | 3 +- x-pack/test/fleet_api_integration/helpers.ts | 12 +++++- 12 files changed, 115 insertions(+), 35 deletions(-) create mode 100644 x-pack/plugins/fleet/public/services/generate_new_agent_policy.test.ts create mode 100644 x-pack/plugins/fleet/public/services/generate_new_agent_policy.ts diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx index 32100ea137930..4e371767c0ece 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx @@ -22,8 +22,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; -import { dataTypes } from '../../../../../../common/constants'; - +import { generateNewAgentPolicyWithDefaults } from '../../../services'; import type { AgentPolicy, NewAgentPolicy } from '../../../types'; import { sendCreateAgentPolicy, useStartServices } from '../../../hooks'; @@ -57,13 +56,12 @@ export const AgentPolicyCreateInlineForm: React.FunctionComponent = ({ const [isLoading, setIsLoading] = useState(false); - const [newAgentPolicy, setNewAgentPolicy] = useState({ - name: agentPolicyName, - description: '', - namespace: 'default', - monitoring_enabled: Object.values(dataTypes), - has_fleet_server: isFleetServerPolicy, - }); + const [newAgentPolicy, setNewAgentPolicy] = useState( + generateNewAgentPolicyWithDefaults({ + name: agentPolicyName, + has_fleet_server: isFleetServerPolicy, + }) + ); const updateNewAgentPolicy = useCallback( (updatedFields: Partial) => { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/hooks/use_get_agent_policy_or_default.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/hooks/use_get_agent_policy_or_default.tsx index 888c6807976d3..0c51b78c8d1af 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/hooks/use_get_agent_policy_or_default.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/hooks/use_get_agent_policy_or_default.tsx @@ -14,6 +14,8 @@ import { sendGetEnrollmentAPIKeys, } from '../../../../../../../hooks'; +import { generateNewAgentPolicyWithDefaults } from '../../../../../../../services'; + import type { AgentPolicy, NewAgentPolicy, EnrollmentAPIKey } from '../../../../../../../types'; interface UseGetAgentPolicyOrDefaultResponse { @@ -24,14 +26,14 @@ interface UseGetAgentPolicyOrDefaultResponse { created?: boolean; } export const DEFAULT_AGENT_POLICY_ID: string = 'fleet-first-agent-policy'; -export const DEFAULT_AGENT_POLICY: NewAgentPolicy = Object.freeze({ - id: DEFAULT_AGENT_POLICY_ID, - name: i18n.translate('xpack.fleet.createPackagePolicy.firstAgentPolicyNameText', { - defaultMessage: 'My first agent policy', - }), - namespace: 'default', - monitoring_enabled: ['logs', 'metrics'] as NewAgentPolicy['monitoring_enabled'], -}); +export const DEFAULT_AGENT_POLICY: NewAgentPolicy = Object.freeze( + generateNewAgentPolicyWithDefaults({ + id: DEFAULT_AGENT_POLICY_ID, + name: i18n.translate('xpack.fleet.createPackagePolicy.firstAgentPolicyNameText', { + defaultMessage: 'My first agent policy', + }), + }) +); const sendGetAgentPolicy = async (agentPolicyId: string) => { let result; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.test.tsx index 0cdc581260b53..5c80b2276ae09 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.test.tsx @@ -383,6 +383,7 @@ describe('when on the package policy create page', () => { monitoring_enabled: ['logs', 'metrics'], name: 'Agent policy 2', namespace: 'default', + inactivity_timeout: 1209600, }, { withSysMonitoring: false } ); @@ -413,6 +414,7 @@ describe('when on the package policy create page', () => { monitoring_enabled: ['logs', 'metrics'], name: 'Agent policy 2', namespace: 'default', + inactivity_timeout: 1209600, }, { withSysMonitoring: true } ); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx index 9146dfe36eee0..cd5b997d9c788 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx @@ -25,7 +25,7 @@ import type { EuiStepProps } from '@elastic/eui/src/components/steps/step'; import { useCancelAddPackagePolicy } from '../hooks'; import { splitPkgKey } from '../../../../../../../common/services'; -import { dataTypes } from '../../../../../../../common/constants'; +import { generateNewAgentPolicyWithDefaults } from '../../../../services'; import type { NewAgentPolicy } from '../../../../types'; import { useConfig, sendGetAgentStatus, useGetPackageInfoByKey } from '../../../../hooks'; import { @@ -80,12 +80,9 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({ } = useConfig(); const { params } = useRouteMatch(); - const [newAgentPolicy, setNewAgentPolicy] = useState({ - name: 'Agent policy 1', - description: '', - namespace: 'default', - monitoring_enabled: Object.values(dataTypes), - }); + const [newAgentPolicy, setNewAgentPolicy] = useState( + generateNewAgentPolicyWithDefaults({ name: 'Agent policy 1' }) + ); const [withSysMonitoring, setWithSysMonitoring] = useState(true); const validation = agentPolicyFormValidation(newAgentPolicy); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/components/create_agent_policy.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/components/create_agent_policy.tsx index ec1b19679760b..2c48eac8923a8 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/components/create_agent_policy.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/components/create_agent_policy.tsx @@ -24,13 +24,15 @@ import { EuiSpacer, } from '@elastic/eui'; -import { dataTypes } from '../../../../../../../common/constants'; import type { NewAgentPolicy, AgentPolicy } from '../../../../types'; import { useAuthz, useStartServices, sendCreateAgentPolicy } from '../../../../hooks'; import { AgentPolicyForm, agentPolicyFormValidation } from '../../components'; import { DevtoolsRequestFlyoutButton } from '../../../../components'; import { generateCreateAgentPolicyDevToolsRequest } from '../../services'; -import { ExperimentalFeaturesService } from '../../../../services'; +import { + ExperimentalFeaturesService, + generateNewAgentPolicyWithDefaults, +} from '../../../../services'; const FlyoutWithHigherZIndex = styled(EuiFlyout)` z-index: ${(props) => props.theme.eui.euiZLevel5}; @@ -47,12 +49,9 @@ export const CreateAgentPolicyFlyout: React.FunctionComponent = ({ }) => { const { notifications } = useStartServices(); const hasFleetAllPrivileges = useAuthz().fleet.all; - const [agentPolicy, setAgentPolicy] = useState({ - name: '', - description: '', - namespace: 'default', - monitoring_enabled: Object.values(dataTypes), - }); + const [agentPolicy, setAgentPolicy] = useState( + generateNewAgentPolicyWithDefaults() + ); const [isLoading, setIsLoading] = useState(false); const [withSysMonitoring, setWithSysMonitoring] = useState(true); const validation = agentPolicyFormValidation(agentPolicy); diff --git a/x-pack/plugins/fleet/public/services/generate_new_agent_policy.test.ts b/x-pack/plugins/fleet/public/services/generate_new_agent_policy.test.ts new file mode 100644 index 0000000000000..5cd6c5d144019 --- /dev/null +++ b/x-pack/plugins/fleet/public/services/generate_new_agent_policy.test.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { generateNewAgentPolicyWithDefaults } from './generate_new_agent_policy'; + +describe('generateNewAgentPolicyWithDefaults', () => { + it('should generate a new agent policy with defaults', () => { + const newAgentPolicy = generateNewAgentPolicyWithDefaults(); + + expect(newAgentPolicy).toEqual({ + name: '', + description: '', + namespace: 'default', + monitoring_enabled: ['logs', 'metrics'], + inactivity_timeout: 1209600, + }); + }); + + it('should override defaults', () => { + const newAgentPolicy = generateNewAgentPolicyWithDefaults({ + name: 'test', + description: 'test description', + namespace: 'test-namespace', + monitoring_enabled: ['logs'], + }); + + expect(newAgentPolicy).toEqual({ + name: 'test', + description: 'test description', + namespace: 'test-namespace', + monitoring_enabled: ['logs'], + inactivity_timeout: 1209600, + }); + }); +}); diff --git a/x-pack/plugins/fleet/public/services/generate_new_agent_policy.ts b/x-pack/plugins/fleet/public/services/generate_new_agent_policy.ts new file mode 100644 index 0000000000000..94fdf5f26632c --- /dev/null +++ b/x-pack/plugins/fleet/public/services/generate_new_agent_policy.ts @@ -0,0 +1,26 @@ +/* + * 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 { dataTypes } from '../../common/constants'; + +import type { NewAgentPolicy } from '../types'; + +const TWO_WEEKS_SECONDS = 1209600; +// create a new agent policy with the defaults set +// used by forms which create new agent policies for initial state value +export function generateNewAgentPolicyWithDefaults( + overrideProps: Partial = {} +): NewAgentPolicy { + return { + name: '', + description: '', + namespace: 'default', + monitoring_enabled: Object.values(dataTypes), + inactivity_timeout: TWO_WEEKS_SECONDS, + ...overrideProps, + }; +} diff --git a/x-pack/plugins/fleet/public/services/index.ts b/x-pack/plugins/fleet/public/services/index.ts index 7f29e0ba452da..07a0d68a22c1c 100644 --- a/x-pack/plugins/fleet/public/services/index.ts +++ b/x-pack/plugins/fleet/public/services/index.ts @@ -49,3 +49,4 @@ export { createExtensionRegistrationCallback } from './ui_extensions'; export { incrementPolicyName } from './increment_policy_name'; export { policyHasFleetServer } from './has_fleet_server'; export { isPackagePrerelease } from './package_prerelease'; +export { generateNewAgentPolicyWithDefaults } from './generate_new_agent_policy'; diff --git a/x-pack/plugins/fleet/server/types/models/agent_policy.ts b/x-pack/plugins/fleet/server/types/models/agent_policy.ts index f709c7b92f89a..750613abfd21a 100644 --- a/x-pack/plugins/fleet/server/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/server/types/models/agent_policy.ts @@ -17,6 +17,8 @@ function validateNonEmptyString(val: string) { } } +const TWO_WEEKS_SECONDS = 1209600; + export const AgentPolicyBaseSchema = { id: schema.maybe(schema.string()), name: schema.string({ minLength: 1, validate: validateNonEmptyString }), @@ -27,7 +29,7 @@ export const AgentPolicyBaseSchema = { is_default: schema.maybe(schema.boolean()), is_default_fleet_server: schema.maybe(schema.boolean()), unenroll_timeout: schema.maybe(schema.number({ min: 0 })), - inactivity_timeout: schema.maybe(schema.number({ min: 0 })), + inactivity_timeout: schema.number({ min: 0, defaultValue: TWO_WEEKS_SECONDS }), monitoring_enabled: schema.maybe( schema.arrayOf( schema.oneOf([schema.literal(dataTypes.Logs), schema.literal(dataTypes.Metrics)]) diff --git a/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts b/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts index b8703cd5a1380..c437197f9cafb 100644 --- a/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts +++ b/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts @@ -58,6 +58,7 @@ export default function (providerContext: FtrProviderContext) { const { body } = await supertest.get(`/api/fleet/agent_policies/${createdPolicy.id}`); expect(body.item.is_managed).to.equal(false); + expect(body.item.inactivity_timeout).to.equal(1209600); expect(body.item.status).to.be('active'); }); @@ -624,6 +625,7 @@ export default function (providerContext: FtrProviderContext) { revision: 2, schema_version: FLEET_AGENT_POLICIES_SCHEMA_VERSION, updated_by: 'elastic', + inactivity_timeout: 1209600, package_policies: [], }); }); @@ -787,6 +789,7 @@ export default function (providerContext: FtrProviderContext) { updated_by: 'elastic', package_policies: [], monitoring_enabled: ['logs', 'metrics'], + inactivity_timeout: 1209600, }); const listResponseAfterUpdate = await fetchPackageList(); diff --git a/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts b/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts index 21d1bc646c5c8..04b8d80fdbee1 100644 --- a/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts +++ b/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts @@ -110,6 +110,7 @@ export default function (providerContext: FtrProviderContext) { await generateAgent(providerContext, 'healthy', `agent-${++agentCount}`, agentPolicy.id); await generateAgent(providerContext, 'offline', `agent-${++agentCount}`, agentPolicy.id); await generateAgent(providerContext, 'error', `agent-${++agentCount}`, agentPolicy.id); + await generateAgent(providerContext, 'inactive', `agent-${++agentCount}`, agentPolicy.id); await generateAgent(providerContext, 'degraded', `agent-${++agentCount}`, agentPolicy.i); await generateAgent( providerContext, @@ -137,7 +138,7 @@ export default function (providerContext: FtrProviderContext) { unhealthy: 3, offline: 1, unenrolled: 0, - inactive: 0, + inactive: 1, updating: 1, total_all_statuses: 8, }); diff --git a/x-pack/test/fleet_api_integration/helpers.ts b/x-pack/test/fleet_api_integration/helpers.ts index c0f1543ee6e85..50bf8ba1ad7e4 100644 --- a/x-pack/test/fleet_api_integration/helpers.ts +++ b/x-pack/test/fleet_api_integration/helpers.ts @@ -52,7 +52,17 @@ export async function generateAgent( data = { policy_revision_idx: 1, last_checkin_status: 'degraded' }; break; case 'offline': - data = { policy_revision_idx: 1, last_checkin: '2017-06-07T18:59:04.498Z' }; + // default inactivity timeout is 2 weeks + // anything less + above offline timeout will be offline + const oneWeekAgoTimestamp = new Date().getTime() - 7 * 24 * 60 * 60 * 1000; + data = { policy_revision_idx: 1, last_checkin: new Date(oneWeekAgoTimestamp).toISOString() }; + break; + case 'inactive': + const threeWeeksAgoTimestamp = new Date().getTime() - 21 * 24 * 60 * 60 * 1000; + data = { + policy_revision_idx: 1, + last_checkin: new Date(threeWeeksAgoTimestamp).toISOString(), + }; break; // Agent with last checkin status as error and currently unenrolling => should displayd updating status case 'error-unenrolling': From dc28138d00badbe7e1485bbf42e01da71efaef0d Mon Sep 17 00:00:00 2001 From: Jiawei Wu <74562234+JiaweiWu@users.noreply.github.com> Date: Tue, 17 Jan 2023 16:40:02 -0800 Subject: [PATCH 21/44] [RAM] [Flapping] Add Flapping Rules Settings (#147774) ## Summary Resolves: https://github.com/elastic/kibana/issues/143529 This PR adds a new saved object `rules-settings` with the schema: ``` properties: { flapping: { properties: { enabled: { type: 'boolean', }, lookBackWindow: { type: 'long', }, statusChangeThreshold: { type: 'long', }, createdBy: { type: 'keyword', }, updatedBy: { type: 'keyword', }, createdAt: { type: 'date', }, updatedAt: { type: 'date', }, }, }, }, ``` It also adds 2 new endpoints: `GET /rules/settings/_flapping` `POST /rules/settings/_flapping` The new rules settings saved object is instantiated per space, using a predetermined ID to enable OCC. This new saved object allows the user to control rules flapping settings for a given space. Access control to the new saved object is done through the kibana features API. A new `RulesSettingsClient` was created and can be used to interact with the settings saved object. This saved object is instantiated lazily. When the code calls `rulesSettingsClient.flapping().get` or `rulesSettingsClient.flapping().update`, we will lazily create a new saved object if one does not exist for the current space. (I have explored bootstrapping this saved object elsewhere but I think this is the easiest solution, I am open to change on this). We have set up the rules settings to support future rule settings sections by making the settings client and permissions modular. Since permission control can be easily extended by using sub features. This PR doesn't contain integration for the `task_runner` to use the flapping settings, but I can do that in this PR if needed. ### Rules settings feature and sub feature (under management) ![rulessettingsprivileges](https://user-images.githubusercontent.com/74562234/210391168-f8dd53d8-21b6-43b1-b653-116c04ad69ed.png) ### Rules settings settings button ![with_permission_rules_config](https://user-images.githubusercontent.com/74562234/208450003-167521de-4222-4705-86cf-8909a6525b18.png) ### Rules settings modal ![rule_config_modal](https://user-images.githubusercontent.com/74562234/208449115-a08150d6-de93-4be7-a19e-7da91496c4a3.png) ### Disabled ![rules_config_modal_disabled](https://user-images.githubusercontent.com/74562234/208450225-8784fcdb-fa27-48cc-9785-e4a8e6360c0e.png) ### Rules settings settings button with insufficient permissions ![no_permission_rules_config](https://user-images.githubusercontent.com/74562234/208450117-9116ecaf-0ca0-4861-b0be-08554587e385.png) ### Rules settings modal with insufficient write subfeature permissions ![no_flapping_permission](https://user-images.githubusercontent.com/74562234/208450263-24a45395-9960-4b55-bbc9-8dbf88646f62.png) ### Rules settings modal with insufficient read subfeature permissions ![Screenshot from 2023-01-03 23-01-48](https://user-images.githubusercontent.com/74562234/210501223-06c9c5cd-73c2-4a11-9889-3a7505e6e0d5.png) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../migrations/check_registered_types.test.ts | 1 + .../migrations/type_registrations.test.ts | 1 + x-pack/plugins/alerting/common/index.ts | 1 + .../plugins/alerting/common/rules_settings.ts | 51 +++ x-pack/plugins/alerting/server/plugin.test.ts | 4 + x-pack/plugins/alerting/server/plugin.ts | 24 +- .../server/routes/_mock_handler_arguments.ts | 6 + .../routes/get_flapping_settings.test.ts | 63 ++++ .../server/routes/get_flapping_settings.ts | 34 ++ .../plugins/alerting/server/routes/index.ts | 4 + .../routes/update_flapping_settings.test.ts | 82 +++++ .../server/routes/update_flapping_settings.ts | 47 +++ .../server/rules_settings_client.mock.ts | 32 ++ .../rules_settings_flapping_client.test.ts | 185 +++++++++++ .../rules_settings_flapping_client.ts | 109 +++++++ .../server/rules_settings_client/index.ts | 9 + .../rules_settings_client.test.ts | 285 +++++++++++++++++ .../rules_settings_client.ts | 114 +++++++ .../rules_settings_client_factory.test.ts | 161 ++++++++++ .../server/rules_settings_client_factory.ts | 67 ++++ .../alerting/server/rules_settings_feature.ts | 91 ++++++ .../alerting/server/saved_objects/index.ts | 9 + .../saved_objects/rules_settings_mappings.ts | 45 +++ x-pack/plugins/alerting/server/types.ts | 5 + .../rules_settings_flapping_form_section.tsx | 213 +++++++++++++ .../rules_settings_link.test.tsx | 150 +++++++++ .../rules_setting/rules_settings_link.tsx | 41 +++ .../rules_settings_modal.test.tsx | 264 ++++++++++++++++ .../rules_setting/rules_settings_modal.tsx | 299 ++++++++++++++++++ .../hooks/use_get_flapping_settings.ts | 53 ++++ .../hooks/use_update_flapping_settings.ts | 57 ++++ .../lib/rule_api/get_flapping_settings.ts | 16 + .../public/application/lib/rule_api/index.ts | 2 + .../lib/rule_api/update_flapping_settings.ts | 34 ++ .../rules_list/components/rules_list.tsx | 9 +- .../tests/alerting/get_flapping_settings.ts | 60 ++++ .../group3/tests/alerting/index.ts | 2 + .../alerting/update_flapping_settings.ts | 154 +++++++++ .../security_and_spaces/scenarios.ts | 6 + .../apis/features/features/features.ts | 1 + .../apis/security/privileges.ts | 8 + .../apis/security/privileges_basic.ts | 9 + .../apps/triggers_actions_ui/index.ts | 1 + .../triggers_actions_ui/rules_settings.ts | 139 ++++++++ 44 files changed, 2944 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugins/alerting/common/rules_settings.ts create mode 100644 x-pack/plugins/alerting/server/routes/get_flapping_settings.test.ts create mode 100644 x-pack/plugins/alerting/server/routes/get_flapping_settings.ts create mode 100644 x-pack/plugins/alerting/server/routes/update_flapping_settings.test.ts create mode 100644 x-pack/plugins/alerting/server/routes/update_flapping_settings.ts create mode 100644 x-pack/plugins/alerting/server/rules_settings_client.mock.ts create mode 100644 x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.test.ts create mode 100644 x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.ts create mode 100644 x-pack/plugins/alerting/server/rules_settings_client/index.ts create mode 100644 x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.test.ts create mode 100644 x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.ts create mode 100644 x-pack/plugins/alerting/server/rules_settings_client_factory.test.ts create mode 100644 x-pack/plugins/alerting/server/rules_settings_client_factory.ts create mode 100644 x-pack/plugins/alerting/server/rules_settings_feature.ts create mode 100644 x-pack/plugins/alerting/server/saved_objects/rules_settings_mappings.ts create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_flapping_form_section.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_link.test.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_link.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_modal.test.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_modal.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/hooks/use_get_flapping_settings.ts create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/hooks/use_update_flapping_settings.ts create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/get_flapping_settings.ts create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update_flapping_settings.ts create mode 100644 x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/get_flapping_settings.ts create mode 100644 x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/update_flapping_settings.ts create mode 100644 x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rules_settings.ts diff --git a/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts b/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts index 8eaef033ad1f3..569e8b81afd2d 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts @@ -124,6 +124,7 @@ describe('checking migration metadata changes on all registered SO types', () => "osquery-pack-asset": "de8783298eb33a577bf1fa0caacd42121dcfae91", "osquery-saved-query": "7b213b4b7a3e59350e99c50e8df9948662ed493a", "query": "4640ef356321500a678869f24117b7091a911cb6", + "rules-settings": "1af4c9abd4b40a154e233c2af4867df7aab7ac24", "sample-data-telemetry": "8b10336d9efae6f3d5593c4cc89fb4abcdf84e04", "search": "c48f5ab5d94545780ea98de1bff9e39f17f3606b", "search-session": "ba383309da68a15be3765977f7a44c84f0ec7964", diff --git a/src/core/server/integration_tests/saved_objects/migrations/type_registrations.test.ts b/src/core/server/integration_tests/saved_objects/migrations/type_registrations.test.ts index 2cb85526f9340..2c8dbabf878a1 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/type_registrations.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/type_registrations.test.ts @@ -92,6 +92,7 @@ const previouslyRegisteredTypes = [ 'osquery-usage-metric', 'osquery-manager-usage-metric', 'query', + 'rules-settings', 'sample-data-telemetry', 'search', 'search-session', diff --git a/x-pack/plugins/alerting/common/index.ts b/x-pack/plugins/alerting/common/index.ts index 795a05dcb802c..9a977213d4446 100644 --- a/x-pack/plugins/alerting/common/index.ts +++ b/x-pack/plugins/alerting/common/index.ts @@ -11,6 +11,7 @@ import { AlertsHealth } from './rule'; export * from './rule'; +export * from './rules_settings'; export * from './rule_type'; export * from './rule_task_instance'; export * from './rule_navigation'; diff --git a/x-pack/plugins/alerting/common/rules_settings.ts b/x-pack/plugins/alerting/common/rules_settings.ts new file mode 100644 index 0000000000000..755becc8a9822 --- /dev/null +++ b/x-pack/plugins/alerting/common/rules_settings.ts @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +export interface RulesSettingsModificationMetadata { + createdBy: string | null; + updatedBy: string | null; + createdAt: string; + updatedAt: string; +} + +export interface RulesSettingsFlappingProperties { + enabled: boolean; + lookBackWindow: number; + statusChangeThreshold: number; +} + +export type RulesSettingsFlapping = RulesSettingsFlappingProperties & + RulesSettingsModificationMetadata; + +export interface RulesSettings { + flapping: RulesSettingsFlapping; +} + +export const MIN_LOOK_BACK_WINDOW = 2; +export const MAX_LOOK_BACK_WINDOW = 20; +export const MIN_STATUS_CHANGE_THRESHOLD = 2; +export const MAX_STATUS_CHANGE_THRESHOLD = 20; + +export const RULES_SETTINGS_FEATURE_ID = 'rulesSettings'; +export const ALL_FLAPPING_SETTINGS_SUB_FEATURE_ID = 'allFlappingSettings'; +export const READ_FLAPPING_SETTINGS_SUB_FEATURE_ID = 'readFlappingSettings'; + +export const API_PRIVILEGES = { + READ_FLAPPING_SETTINGS: 'read-flapping-settings', + WRITE_FLAPPING_SETTINGS: 'write-flapping-settings', +}; + +export const RULES_SETTINGS_SAVED_OBJECT_TYPE = 'rules-settings'; +export const RULES_SETTINGS_SAVED_OBJECT_ID = 'rules-settings'; + +export const DEFAULT_LOOK_BACK_WINDOW = 20; +export const DEFAULT_STATUS_CHANGE_THRESHOLD = 4; + +export const DEFAULT_FLAPPING_SETTINGS = { + enabled: true, + lookBackWindow: 20, + statusChangeThreshold: 4, +}; diff --git a/x-pack/plugins/alerting/server/plugin.test.ts b/x-pack/plugins/alerting/server/plugin.test.ts index 2c057cc4cfc43..7b85bc898fee0 100644 --- a/x-pack/plugins/alerting/server/plugin.test.ts +++ b/x-pack/plugins/alerting/server/plugin.test.ts @@ -78,6 +78,7 @@ describe('Alerting Plugin', () => { statusService: statusServiceMock.createSetupContract(), monitoringCollection: monitoringCollectionMock.createSetup(), data: dataPluginMock.createSetupContract() as unknown as DataPluginSetup, + features: featuresPluginMock.createSetup(), }; let plugin: AlertingPlugin; @@ -221,6 +222,7 @@ describe('Alerting Plugin', () => { statusService: statusServiceMock.createSetupContract(), monitoringCollection: monitoringCollectionMock.createSetup(), data: dataPluginMock.createSetupContract() as unknown as DataPluginSetup, + features: featuresPluginMock.createSetup(), }); const startContract = plugin.start(coreMock.createStart(), { @@ -267,6 +269,7 @@ describe('Alerting Plugin', () => { statusService: statusServiceMock.createSetupContract(), monitoringCollection: monitoringCollectionMock.createSetup(), data: dataPluginMock.createSetupContract() as unknown as DataPluginSetup, + features: featuresPluginMock.createSetup(), }); const startContract = plugin.start(coreMock.createStart(), { @@ -324,6 +327,7 @@ describe('Alerting Plugin', () => { statusService: statusServiceMock.createSetupContract(), monitoringCollection: monitoringCollectionMock.createSetup(), data: dataPluginMock.createSetupContract() as unknown as DataPluginSetup, + features: featuresPluginMock.createSetup(), }); const startContract = plugin.start(coreMock.createStart(), { diff --git a/x-pack/plugins/alerting/server/plugin.ts b/x-pack/plugins/alerting/server/plugin.ts index 13f39504d2781..86d8a7411c16d 100644 --- a/x-pack/plugins/alerting/server/plugin.ts +++ b/x-pack/plugins/alerting/server/plugin.ts @@ -47,13 +47,17 @@ import { IEventLogService, IEventLogClientService, } from '@kbn/event-log-plugin/server'; -import { PluginStartContract as FeaturesPluginStart } from '@kbn/features-plugin/server'; +import { + PluginStartContract as FeaturesPluginStart, + PluginSetupContract as FeaturesPluginSetup, +} from '@kbn/features-plugin/server'; import { PluginStart as DataPluginStart } from '@kbn/data-plugin/server'; import { MonitoringCollectionSetup } from '@kbn/monitoring-collection-plugin/server'; import { SharePluginStart } from '@kbn/share-plugin/server'; import { RuleTypeRegistry } from './rule_type_registry'; import { TaskRunnerFactory } from './task_runner'; import { RulesClientFactory } from './rules_client_factory'; +import { RulesSettingsClientFactory } from './rules_settings_client_factory'; import { ILicenseState, LicenseState } from './lib/license_state'; import { AlertingRequestHandlerContext, ALERTS_FEATURE_ID } from './types'; import { defineRoutes } from './routes'; @@ -82,6 +86,7 @@ import { getSecurityHealth, SecurityHealth } from './lib/get_security_health'; import { registerNodeCollector, registerClusterCollector, InMemoryMetrics } from './monitoring'; import { getRuleTaskTimeout } from './lib/get_rule_task_timeout'; import { getActionsConfigMap } from './lib/get_actions_config_map'; +import { rulesSettingsFeature } from './rules_settings_feature'; export const EVENT_LOG_PROVIDER = 'alerting'; export const EVENT_LOG_ACTIONS = { @@ -146,6 +151,7 @@ export interface AlertingPluginsSetup { statusService: StatusServiceSetup; monitoringCollection: MonitoringCollectionSetup; data: DataPluginSetup; + features: FeaturesPluginSetup; } export interface AlertingPluginsStart { @@ -172,6 +178,7 @@ export class AlertingPlugin { private security?: SecurityPluginSetup; private readonly rulesClientFactory: RulesClientFactory; private readonly alertingAuthorizationClientFactory: AlertingAuthorizationClientFactory; + private readonly rulesSettingsClientFactory: RulesSettingsClientFactory; private readonly telemetryLogger: Logger; private readonly kibanaVersion: PluginInitializerContext['env']['packageInfo']['version']; private eventLogService?: IEventLogService; @@ -186,6 +193,7 @@ export class AlertingPlugin { this.taskRunnerFactory = new TaskRunnerFactory(); this.rulesClientFactory = new RulesClientFactory(); this.alertingAuthorizationClientFactory = new AlertingAuthorizationClientFactory(); + this.rulesSettingsClientFactory = new RulesSettingsClientFactory(); this.telemetryLogger = initializerContext.logger.get('usage'); this.kibanaVersion = initializerContext.env.packageInfo.version; this.inMemoryMetrics = new InMemoryMetrics(initializerContext.logger.get('in_memory_metrics')); @@ -210,6 +218,8 @@ export class AlertingPlugin { }; }); + plugins.features.registerKibanaFeature(rulesSettingsFeature); + this.isESOCanEncrypt = plugins.encryptedSavedObjects.canEncrypt; if (!this.isESOCanEncrypt) { @@ -368,6 +378,7 @@ export class AlertingPlugin { ruleTypeRegistry, rulesClientFactory, alertingAuthorizationClientFactory, + rulesSettingsClientFactory, security, licenseState, } = this; @@ -416,6 +427,12 @@ export class AlertingPlugin { minimumScheduleInterval: this.config.rules.minimumScheduleInterval, }); + rulesSettingsClientFactory.initialize({ + logger: this.logger, + savedObjectsService: core.savedObjects, + securityPluginStart: plugins.security, + }); + const getRulesClientWithRequest = (request: KibanaRequest) => { if (isESOCanEncrypt !== true) { throw new Error( @@ -483,13 +500,16 @@ export class AlertingPlugin { private createRouteHandlerContext = ( core: CoreSetup ): IContextProvider => { - const { ruleTypeRegistry, rulesClientFactory } = this; + const { ruleTypeRegistry, rulesClientFactory, rulesSettingsClientFactory } = this; return async function alertsRouteHandlerContext(context, request) { const [{ savedObjects }] = await core.getStartServices(); return { getRulesClient: () => { return rulesClientFactory!.create(request, savedObjects); }, + getRulesSettingsClient: () => { + return rulesSettingsClientFactory.createWithAuthorization(request); + }, listTypes: ruleTypeRegistry!.list.bind(ruleTypeRegistry!), getFrameworkHealth: async () => await getHealth(savedObjects.createInternalRepository(['alert'])), diff --git a/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts b/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts index b5fbaa3d0cf86..0df0f371f62b6 100644 --- a/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts +++ b/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts @@ -10,17 +10,20 @@ import { identity } from 'lodash'; import type { MethodKeysOf } from '@kbn/utility-types'; import { httpServerMock } from '@kbn/core/server/mocks'; import { rulesClientMock, RulesClientMock } from '../rules_client.mock'; +import { rulesSettingsClientMock, RulesSettingsClientMock } from '../rules_settings_client.mock'; import { AlertsHealth, RuleType } from '../../common'; import type { AlertingRequestHandlerContext } from '../types'; export function mockHandlerArguments( { rulesClient = rulesClientMock.create(), + rulesSettingsClient = rulesSettingsClientMock.create(), listTypes: listTypesRes = [], getFrameworkHealth, areApiKeysEnabled, }: { rulesClient?: RulesClientMock; + rulesSettingsClient?: RulesSettingsClientMock; listTypes?: RuleType[]; getFrameworkHealth?: jest.MockInstance, []> & (() => Promise); @@ -41,6 +44,9 @@ export function mockHandlerArguments( getRulesClient() { return rulesClient || rulesClientMock.create(); }, + getRulesSettingsClient() { + return rulesSettingsClient || rulesSettingsClientMock.create(); + }, getFrameworkHealth, areApiKeysEnabled: areApiKeysEnabled ? areApiKeysEnabled : () => Promise.resolve(true), }, diff --git a/x-pack/plugins/alerting/server/routes/get_flapping_settings.test.ts b/x-pack/plugins/alerting/server/routes/get_flapping_settings.test.ts new file mode 100644 index 0000000000000..156ab604fb905 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/get_flapping_settings.test.ts @@ -0,0 +1,63 @@ +/* + * 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 { httpServiceMock } from '@kbn/core/server/mocks'; +import { licenseStateMock } from '../lib/license_state.mock'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { rulesSettingsClientMock, RulesSettingsClientMock } from '../rules_settings_client.mock'; +import { getFlappingSettingsRoute } from './get_flapping_settings'; + +let rulesSettingsClient: RulesSettingsClientMock; + +jest.mock('../lib/license_api_access', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); + rulesSettingsClient = rulesSettingsClientMock.create(); +}); + +describe('getFlappingSettingsRoute', () => { + test('gets flapping settings', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + getFlappingSettingsRoute(router, licenseState); + + const [config, handler] = router.get.mock.calls[0]; + + expect(config).toMatchInlineSnapshot(` + Object { + "options": Object { + "tags": Array [ + "access:read-flapping-settings", + ], + }, + "path": "/internal/alerting/rules/settings/_flapping", + "validate": false, + } + `); + + (rulesSettingsClient.flapping().get as jest.Mock).mockResolvedValue({ + enabled: true, + lookBackWindow: 10, + statusChangeThreshold: 10, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }); + + const [context, req, res] = mockHandlerArguments({ rulesSettingsClient }, {}, ['ok']); + + await handler(context, req, res); + + expect(rulesSettingsClient.flapping().get).toHaveBeenCalledTimes(1); + expect(res.ok).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/get_flapping_settings.ts b/x-pack/plugins/alerting/server/routes/get_flapping_settings.ts new file mode 100644 index 0000000000000..6ae039032994d --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/get_flapping_settings.ts @@ -0,0 +1,34 @@ +/* + * 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 { IRouter } from '@kbn/core/server'; +import { ILicenseState } from '../lib'; +import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../types'; +import { verifyAccessAndContext } from './lib'; +import { API_PRIVILEGES } from '../../common'; + +export const getFlappingSettingsRoute = ( + router: IRouter, + licenseState: ILicenseState +) => { + router.get( + { + path: `${INTERNAL_BASE_ALERTING_API_PATH}/rules/settings/_flapping`, + validate: false, + options: { + tags: [`access:${API_PRIVILEGES.READ_FLAPPING_SETTINGS}`], + }, + }, + router.handleLegacyErrors( + verifyAccessAndContext(licenseState, async function (context, req, res) { + const rulesSettingsClient = (await context.alerting).getRulesSettingsClient(); + const flappingSettings = await rulesSettingsClient.flapping().get(); + return res.ok({ body: flappingSettings }); + }) + ) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/index.ts b/x-pack/plugins/alerting/server/routes/index.ts index c4c62a92cbede..32deff30edd7c 100644 --- a/x-pack/plugins/alerting/server/routes/index.ts +++ b/x-pack/plugins/alerting/server/routes/index.ts @@ -42,6 +42,8 @@ import { bulkDeleteRulesRoute } from './bulk_delete_rules'; import { bulkEnableRulesRoute } from './bulk_enable_rules'; import { bulkDisableRulesRoute } from './bulk_disable_rules'; import { cloneRuleRoute } from './clone_rule'; +import { getFlappingSettingsRoute } from './get_flapping_settings'; +import { updateFlappingSettingsRoute } from './update_flapping_settings'; export interface RouteOptions { router: IRouter; @@ -87,4 +89,6 @@ export function defineRoutes(opts: RouteOptions) { unsnoozeRuleRoute(router, licenseState); runSoonRoute(router, licenseState); cloneRuleRoute(router, licenseState); + getFlappingSettingsRoute(router, licenseState); + updateFlappingSettingsRoute(router, licenseState); } diff --git a/x-pack/plugins/alerting/server/routes/update_flapping_settings.test.ts b/x-pack/plugins/alerting/server/routes/update_flapping_settings.test.ts new file mode 100644 index 0000000000000..28914e71e7dd3 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/update_flapping_settings.test.ts @@ -0,0 +1,82 @@ +/* + * 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 { httpServiceMock } from '@kbn/core/server/mocks'; +import { licenseStateMock } from '../lib/license_state.mock'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { rulesSettingsClientMock, RulesSettingsClientMock } from '../rules_settings_client.mock'; +import { updateFlappingSettingsRoute } from './update_flapping_settings'; + +let rulesSettingsClient: RulesSettingsClientMock; + +jest.mock('../lib/license_api_access', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); + rulesSettingsClient = rulesSettingsClientMock.create(); +}); + +describe('updateFlappingSettingsRoute', () => { + test('updates flapping settings', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + updateFlappingSettingsRoute(router, licenseState); + + const [config, handler] = router.post.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/internal/alerting/rules/settings/_flapping"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:write-flapping-settings", + ], + } + `); + + (rulesSettingsClient.flapping().get as jest.Mock).mockResolvedValue({ + enabled: true, + lookBackWindow: 10, + statusChangeThreshold: 10, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }); + + const updateResult = { + enabled: false, + lookBackWindow: 6, + statusChangeThreshold: 5, + }; + + const [context, req, res] = mockHandlerArguments( + { rulesSettingsClient }, + { + body: updateResult, + }, + ['ok'] + ); + + await handler(context, req, res); + + expect(rulesSettingsClient.flapping().update).toHaveBeenCalledTimes(1); + expect((rulesSettingsClient.flapping().update as jest.Mock).mock.calls[0]) + .toMatchInlineSnapshot(` + Array [ + Object { + "enabled": false, + "lookBackWindow": 6, + "statusChangeThreshold": 5, + }, + ] + `); + expect(res.ok).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/update_flapping_settings.ts b/x-pack/plugins/alerting/server/routes/update_flapping_settings.ts new file mode 100644 index 0000000000000..ede33a7d36a95 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/update_flapping_settings.ts @@ -0,0 +1,47 @@ +/* + * 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 { IRouter } from '@kbn/core/server'; +import { schema } from '@kbn/config-schema'; +import { ILicenseState } from '../lib'; +import { verifyAccessAndContext } from './lib'; +import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../types'; +import { API_PRIVILEGES } from '../../common'; + +const bodySchema = schema.object({ + enabled: schema.boolean(), + lookBackWindow: schema.number(), + statusChangeThreshold: schema.number(), +}); + +export const updateFlappingSettingsRoute = ( + router: IRouter, + licenseState: ILicenseState +) => { + router.post( + { + path: `${INTERNAL_BASE_ALERTING_API_PATH}/rules/settings/_flapping`, + validate: { + body: bodySchema, + }, + options: { + tags: [`access:${API_PRIVILEGES.WRITE_FLAPPING_SETTINGS}`], + }, + }, + router.handleLegacyErrors( + verifyAccessAndContext(licenseState, async function (context, req, res) { + const rulesSettingsClient = (await context.alerting).getRulesSettingsClient(); + + const updatedFlappingSettings = await rulesSettingsClient.flapping().update(req.body); + + return res.ok({ + body: updatedFlappingSettings, + }); + }) + ) + ); +}; diff --git a/x-pack/plugins/alerting/server/rules_settings_client.mock.ts b/x-pack/plugins/alerting/server/rules_settings_client.mock.ts new file mode 100644 index 0000000000000..2c321e54ebf71 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client.mock.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { RulesSettingsClientApi, RulesSettingsFlappingClientApi } from './types'; + +export type RulesSettingsClientMock = jest.Mocked; +export type RulesSettingsFlappingClientMock = jest.Mocked; + +// Warning: Becareful when resetting all mocks in tests as it would clear +// the mock return value on the flapping +const createRulesSettingsClientMock = () => { + const flappingMocked: RulesSettingsFlappingClientMock = { + get: jest.fn(), + update: jest.fn(), + }; + const mocked: RulesSettingsClientMock = { + get: jest.fn(), + create: jest.fn(), + flapping: jest.fn().mockReturnValue(flappingMocked), + }; + return mocked; +}; + +export const rulesSettingsClientMock: { + create: () => RulesSettingsClientMock; +} = { + create: createRulesSettingsClientMock, +}; diff --git a/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.test.ts b/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.test.ts new file mode 100644 index 0000000000000..ca69100fcfaed --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.test.ts @@ -0,0 +1,185 @@ +/* + * 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 { + RulesSettingsFlappingClient, + RulesSettingsFlappingClientConstructorOptions, +} from './rules_settings_flapping_client'; +import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; +import { + RULES_SETTINGS_FEATURE_ID, + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID, + DEFAULT_FLAPPING_SETTINGS, + RulesSettings, +} from '../../../common'; + +const mockDateString = '2019-02-12T21:01:22.479Z'; + +const savedObjectsClient = savedObjectsClientMock.create(); + +const getMockRulesSettings = (): RulesSettings => { + return { + flapping: { + enabled: DEFAULT_FLAPPING_SETTINGS.enabled, + lookBackWindow: DEFAULT_FLAPPING_SETTINGS.lookBackWindow, + statusChangeThreshold: DEFAULT_FLAPPING_SETTINGS.statusChangeThreshold, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }, + }; +}; + +const rulesSettingsFlappingClientParams: jest.Mocked = + { + logger: loggingSystemMock.create().get(), + getOrCreate: jest.fn().mockReturnValue({ + id: RULES_SETTINGS_FEATURE_ID, + type: RULES_SETTINGS_SAVED_OBJECT_TYPE, + attributes: getMockRulesSettings(), + references: [], + version: '123', + }), + getModificationMetadata: jest.fn(), + savedObjectsClient, + }; + +describe('RulesSettingsFlappingClient', () => { + beforeAll(() => { + jest.useFakeTimers(); + jest.setSystemTime(new Date(mockDateString)); + }); + + afterAll(() => { + jest.clearAllMocks(); + jest.useRealTimers(); + }); + + test('can get flapping settings', async () => { + const client = new RulesSettingsFlappingClient(rulesSettingsFlappingClientParams); + const result = await client.get(); + + expect(result).toEqual( + expect.objectContaining({ + enabled: DEFAULT_FLAPPING_SETTINGS.enabled, + lookBackWindow: DEFAULT_FLAPPING_SETTINGS.lookBackWindow, + statusChangeThreshold: DEFAULT_FLAPPING_SETTINGS.statusChangeThreshold, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: expect.any(String), + updatedAt: expect.any(String), + }) + ); + }); + + test('can update flapping settings', async () => { + const client = new RulesSettingsFlappingClient(rulesSettingsFlappingClientParams); + + const mockResolve = { + id: RULES_SETTINGS_FEATURE_ID, + type: RULES_SETTINGS_SAVED_OBJECT_TYPE, + attributes: getMockRulesSettings(), + references: [], + version: '123', + }; + + savedObjectsClient.update.mockResolvedValueOnce({ + ...mockResolve, + attributes: { + flapping: { + ...mockResolve.attributes.flapping, + enabled: false, + lookBackWindow: 19, + statusChangeThreshold: 3, + }, + }, + }); + + const result = await client.update({ + enabled: false, + lookBackWindow: 19, + statusChangeThreshold: 3, + }); + + expect(savedObjectsClient.update).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID, + { + flapping: expect.objectContaining({ + enabled: false, + lookBackWindow: 19, + statusChangeThreshold: 3, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: expect.any(String), + updatedAt: expect.any(String), + }), + }, + { version: '123' } + ); + + expect(result).toEqual( + expect.objectContaining({ + enabled: false, + lookBackWindow: 19, + statusChangeThreshold: 3, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: expect.any(String), + updatedAt: expect.any(String), + }) + ); + }); + + test('throws if savedObjectsClient failed to update', async () => { + const client = new RulesSettingsFlappingClient(rulesSettingsFlappingClientParams); + savedObjectsClient.update.mockRejectedValueOnce(new Error('failed!!')); + + await expect( + client.update({ + enabled: false, + lookBackWindow: 19, + statusChangeThreshold: 3, + }) + ).rejects.toThrowError( + 'savedObjectsClient errored trying to update flapping settings: failed!!' + ); + }); + + test('throws if new flapping setting fails verification', async () => { + const client = new RulesSettingsFlappingClient(rulesSettingsFlappingClientParams); + await expect( + client.update({ + enabled: true, + lookBackWindow: 200, + statusChangeThreshold: 500, + }) + ).rejects.toThrowError('Invalid lookBackWindow value, must be between 2 and 20, but got: 200.'); + + await expect( + client.update({ + enabled: true, + lookBackWindow: 20, + statusChangeThreshold: 500, + }) + ).rejects.toThrowError( + 'Invalid statusChangeThreshold value, must be between 2 and 20, but got: 500.' + ); + + await expect( + client.update({ + enabled: true, + lookBackWindow: 10, + statusChangeThreshold: 20, + }) + ).rejects.toThrowError( + 'Invalid values,lookBackWindow (10) must be equal to or greater than statusChangeThreshold (20).' + ); + }); +}); diff --git a/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.ts b/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.ts new file mode 100644 index 0000000000000..65db68aaba525 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.ts @@ -0,0 +1,109 @@ +/* + * 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 Boom from '@hapi/boom'; +import { Logger, SavedObjectsClientContract, SavedObject } from '@kbn/core/server'; +import { + RulesSettings, + RulesSettingsFlapping, + RulesSettingsFlappingProperties, + RulesSettingsModificationMetadata, + MIN_LOOK_BACK_WINDOW, + MAX_LOOK_BACK_WINDOW, + MIN_STATUS_CHANGE_THRESHOLD, + MAX_STATUS_CHANGE_THRESHOLD, + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID, +} from '../../../common'; + +const verifyFlappingSettings = (flappingSettings: RulesSettingsFlappingProperties) => { + const { lookBackWindow, statusChangeThreshold } = flappingSettings; + + if (lookBackWindow < MIN_LOOK_BACK_WINDOW || lookBackWindow > MAX_LOOK_BACK_WINDOW) { + throw Boom.badRequest( + `Invalid lookBackWindow value, must be between ${MIN_LOOK_BACK_WINDOW} and ${MAX_LOOK_BACK_WINDOW}, but got: ${lookBackWindow}.` + ); + } + + if ( + statusChangeThreshold < MIN_STATUS_CHANGE_THRESHOLD || + statusChangeThreshold > MAX_STATUS_CHANGE_THRESHOLD + ) { + throw Boom.badRequest( + `Invalid statusChangeThreshold value, must be between ${MIN_STATUS_CHANGE_THRESHOLD} and ${MAX_STATUS_CHANGE_THRESHOLD}, but got: ${statusChangeThreshold}.` + ); + } + + if (lookBackWindow < statusChangeThreshold) { + throw Boom.badRequest( + `Invalid values,lookBackWindow (${lookBackWindow}) must be equal to or greater than statusChangeThreshold (${statusChangeThreshold}).` + ); + } +}; + +export interface RulesSettingsFlappingClientConstructorOptions { + readonly logger: Logger; + readonly savedObjectsClient: SavedObjectsClientContract; + readonly getOrCreate: () => Promise>; + readonly getModificationMetadata: () => Promise; +} + +export class RulesSettingsFlappingClient { + private readonly logger: Logger; + private readonly savedObjectsClient: SavedObjectsClientContract; + private readonly getOrCreate: () => Promise>; + private readonly getModificationMetadata: () => Promise; + + constructor(options: RulesSettingsFlappingClientConstructorOptions) { + this.logger = options.logger; + this.savedObjectsClient = options.savedObjectsClient; + this.getOrCreate = options.getOrCreate; + this.getModificationMetadata = options.getModificationMetadata; + } + + public async get(): Promise { + const rulesSettings = await this.getOrCreate(); + return rulesSettings.attributes.flapping; + } + + public async update(newFlappingProperties: RulesSettingsFlappingProperties) { + try { + verifyFlappingSettings(newFlappingProperties); + } catch (e) { + this.logger.error( + `Failed to verify new flapping settings properties when updating. Error: ${e}` + ); + throw e; + } + + const { attributes, version } = await this.getOrCreate(); + const modificationMetadata = await this.getModificationMetadata(); + + try { + const result = await this.savedObjectsClient.update( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID, + { + ...attributes, + flapping: { + ...attributes.flapping, + ...newFlappingProperties, + ...modificationMetadata, + }, + }, + { + version, + } + ); + return result.attributes.flapping; + } catch (e) { + const errorMessage = 'savedObjectsClient errored trying to update flapping settings'; + this.logger.error(`${errorMessage}: ${e}`); + throw Boom.boomify(e, { message: errorMessage }); + } + } +} diff --git a/x-pack/plugins/alerting/server/rules_settings_client/index.ts b/x-pack/plugins/alerting/server/rules_settings_client/index.ts new file mode 100644 index 0000000000000..efbb3f0b3ccfe --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './rules_settings_client'; +export * from './flapping/rules_settings_flapping_client'; diff --git a/x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.test.ts b/x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.test.ts new file mode 100644 index 0000000000000..a40c491b9117e --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.test.ts @@ -0,0 +1,285 @@ +/* + * 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 { + RulesSettingsClient, + RulesSettingsClientConstructorOptions, +} from './rules_settings_client'; +import { RulesSettingsFlappingClient } from './flapping/rules_settings_flapping_client'; +import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; +import { SavedObjectsErrorHelpers } from '@kbn/core/server'; +import { + RULES_SETTINGS_FEATURE_ID, + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID, + DEFAULT_FLAPPING_SETTINGS, + RulesSettings, +} from '../../common'; + +const mockDateString = '2019-02-12T21:01:22.479Z'; + +const savedObjectsClient = savedObjectsClientMock.create(); + +const rulesSettingsClientParams: jest.Mocked = { + logger: loggingSystemMock.create().get(), + getUserName: jest.fn(), + savedObjectsClient, +}; + +const getMockRulesSettings = (): RulesSettings => { + return { + flapping: { + enabled: DEFAULT_FLAPPING_SETTINGS.enabled, + lookBackWindow: DEFAULT_FLAPPING_SETTINGS.lookBackWindow, + statusChangeThreshold: DEFAULT_FLAPPING_SETTINGS.statusChangeThreshold, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }, + }; +}; + +describe('RulesSettingsClient', () => { + beforeAll(() => { + jest.useFakeTimers(); + jest.setSystemTime(new Date(mockDateString)); + }); + + afterAll(() => { + jest.useRealTimers(); + }); + + beforeEach(() => { + jest.resetAllMocks(); + rulesSettingsClientParams.getUserName.mockResolvedValue('test name'); + }); + + test('can initialize correctly', async () => { + const client = new RulesSettingsClient(rulesSettingsClientParams); + expect(client.flapping()).toEqual(expect.any(RulesSettingsFlappingClient)); + }); + + test('can create a new rules settings saved object', async () => { + const client = new RulesSettingsClient(rulesSettingsClientParams); + const mockAttributes = getMockRulesSettings(); + + savedObjectsClient.create.mockResolvedValueOnce({ + id: RULES_SETTINGS_FEATURE_ID, + type: RULES_SETTINGS_SAVED_OBJECT_TYPE, + attributes: mockAttributes, + references: [], + }); + + const result = await client.create(); + + expect(savedObjectsClient.create).toHaveBeenCalledTimes(1); + expect(savedObjectsClient.create).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + { + flapping: expect.objectContaining({ + enabled: mockAttributes.flapping.enabled, + lookBackWindow: mockAttributes.flapping.lookBackWindow, + statusChangeThreshold: mockAttributes.flapping.statusChangeThreshold, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: expect.any(String), + updatedAt: expect.any(String), + }), + }, + { + id: RULES_SETTINGS_SAVED_OBJECT_ID, + overwrite: true, + } + ); + expect(result.attributes).toEqual(mockAttributes); + }); + + test('can get existing rules settings saved object', async () => { + const client = new RulesSettingsClient(rulesSettingsClientParams); + const mockAttributes = getMockRulesSettings(); + + savedObjectsClient.get.mockResolvedValueOnce({ + id: RULES_SETTINGS_FEATURE_ID, + type: RULES_SETTINGS_SAVED_OBJECT_TYPE, + attributes: mockAttributes, + references: [], + }); + const result = await client.get(); + expect(result.attributes).toEqual(mockAttributes); + }); + + test('throws if there is no existing saved object to get', async () => { + const client = new RulesSettingsClient(rulesSettingsClientParams); + + savedObjectsClient.get.mockRejectedValueOnce( + SavedObjectsErrorHelpers.createGenericNotFoundError( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID + ) + ); + await expect(client.get()).rejects.toThrowError(); + }); + + test('can persist flapping settings when saved object does not exist', async () => { + const client = new RulesSettingsClient(rulesSettingsClientParams); + const mockAttributes = getMockRulesSettings(); + savedObjectsClient.get.mockRejectedValueOnce( + SavedObjectsErrorHelpers.createGenericNotFoundError( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID + ) + ); + + savedObjectsClient.create.mockResolvedValueOnce({ + id: RULES_SETTINGS_FEATURE_ID, + type: RULES_SETTINGS_SAVED_OBJECT_TYPE, + attributes: mockAttributes, + references: [], + }); + + const result = await client.flapping().get(); + + expect(savedObjectsClient.get).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID + ); + + expect(savedObjectsClient.create).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + { + flapping: expect.objectContaining({ + enabled: mockAttributes.flapping.enabled, + lookBackWindow: mockAttributes.flapping.lookBackWindow, + statusChangeThreshold: mockAttributes.flapping.statusChangeThreshold, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: expect.any(String), + updatedAt: expect.any(String), + }), + }, + { + id: RULES_SETTINGS_SAVED_OBJECT_ID, + overwrite: true, + } + ); + expect(result).toEqual(mockAttributes.flapping); + }); + + test('can persist flapping settings when saved object already exists', async () => { + const client = new RulesSettingsClient(rulesSettingsClientParams); + const mockAttributes = getMockRulesSettings(); + + savedObjectsClient.get.mockResolvedValueOnce({ + id: RULES_SETTINGS_FEATURE_ID, + type: RULES_SETTINGS_SAVED_OBJECT_TYPE, + attributes: mockAttributes, + references: [], + }); + + const result = await client.flapping().get(); + + expect(savedObjectsClient.get).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID + ); + expect(savedObjectsClient.create).not.toHaveBeenCalled(); + expect(result).toEqual(mockAttributes.flapping); + }); + + test('can update flapping settings when saved object does not exist', async () => { + const client = new RulesSettingsClient(rulesSettingsClientParams); + const mockAttributes = getMockRulesSettings(); + + savedObjectsClient.get.mockRejectedValueOnce( + SavedObjectsErrorHelpers.createGenericNotFoundError( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID + ) + ); + + const mockResolve = { + id: RULES_SETTINGS_FEATURE_ID, + type: RULES_SETTINGS_SAVED_OBJECT_TYPE, + attributes: mockAttributes, + references: [], + version: '123', + }; + + savedObjectsClient.create.mockResolvedValueOnce(mockResolve); + savedObjectsClient.update.mockResolvedValueOnce({ + ...mockResolve, + attributes: { + flapping: { + ...mockResolve.attributes.flapping, + enabled: false, + lookBackWindow: 5, + statusChangeThreshold: 5, + }, + }, + }); + + // Try to update with new values + const result = await client.flapping().update({ + enabled: false, + lookBackWindow: 5, + statusChangeThreshold: 5, + }); + + // Tried to get first, but no results + expect(savedObjectsClient.get).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID + ); + + // So create a new entry + expect(savedObjectsClient.create).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + { + flapping: expect.objectContaining({ + enabled: mockAttributes.flapping.enabled, + lookBackWindow: mockAttributes.flapping.lookBackWindow, + statusChangeThreshold: mockAttributes.flapping.statusChangeThreshold, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: expect.any(String), + updatedAt: expect.any(String), + }), + }, + { + id: RULES_SETTINGS_SAVED_OBJECT_ID, + overwrite: true, + } + ); + + // Try to update with version + expect(savedObjectsClient.update).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID, + { + flapping: expect.objectContaining({ + enabled: false, + lookBackWindow: 5, + statusChangeThreshold: 5, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: expect.any(String), + updatedAt: expect.any(String), + }), + }, + { version: '123' } + ); + + expect(result).toEqual( + expect.objectContaining({ + enabled: false, + lookBackWindow: 5, + statusChangeThreshold: 5, + }) + ); + }); +}); diff --git a/x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.ts b/x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.ts new file mode 100644 index 0000000000000..1a99ab5644246 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.ts @@ -0,0 +1,114 @@ +/* + * 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 { + Logger, + SavedObjectsClientContract, + SavedObject, + SavedObjectsErrorHelpers, +} from '@kbn/core/server'; +import { RulesSettingsFlappingClient } from './flapping/rules_settings_flapping_client'; +import { + RulesSettings, + DEFAULT_FLAPPING_SETTINGS, + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID, +} from '../../common'; + +export interface RulesSettingsClientConstructorOptions { + readonly logger: Logger; + readonly savedObjectsClient: SavedObjectsClientContract; + readonly getUserName: () => Promise; +} + +export class RulesSettingsClient { + private readonly logger: Logger; + private readonly savedObjectsClient: SavedObjectsClientContract; + private readonly getUserName: () => Promise; + private readonly _flapping: RulesSettingsFlappingClient; + + constructor(options: RulesSettingsClientConstructorOptions) { + this.logger = options.logger; + this.savedObjectsClient = options.savedObjectsClient; + this.getUserName = options.getUserName; + + this._flapping = new RulesSettingsFlappingClient({ + logger: this.logger, + savedObjectsClient: this.savedObjectsClient, + getOrCreate: this.getOrCreate.bind(this), + getModificationMetadata: this.getModificationMetadata.bind(this), + }); + } + + private async getModificationMetadata() { + const createTime = Date.now(); + const userName = await this.getUserName(); + + return { + createdBy: userName, + updatedBy: userName, + createdAt: new Date(createTime).toISOString(), + updatedAt: new Date(createTime).toISOString(), + }; + } + + public async get(): Promise> { + try { + return await this.savedObjectsClient.get( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID + ); + } catch (e) { + this.logger.error(`Failed to get rules setting for current space. Error: ${e}`); + throw e; + } + } + + public async create(): Promise> { + const modificationMetadata = await this.getModificationMetadata(); + + try { + return await this.savedObjectsClient.create( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + { + flapping: { + ...DEFAULT_FLAPPING_SETTINGS, + ...modificationMetadata, + }, + }, + { + id: RULES_SETTINGS_SAVED_OBJECT_ID, + overwrite: true, + } + ); + } catch (e) { + this.logger.error(`Failed to create rules setting for current space. Error: ${e}`); + throw e; + } + } + + /** + * Helper function to ensure that a rules-settings saved object always exists. + * Enabled the creation of the saved object is done lazily during retrieval. + */ + private async getOrCreate(): Promise> { + try { + return await this.get(); + } catch (e) { + if (SavedObjectsErrorHelpers.isNotFoundError(e)) { + this.logger.info('Creating new default rules settings for current space.'); + return await this.create(); + } + this.logger.error(`Failed to persist rules setting for current space. Error: ${e}`); + throw e; + } + } + + public flapping(): RulesSettingsFlappingClient { + return this._flapping; + } +} diff --git a/x-pack/plugins/alerting/server/rules_settings_client_factory.test.ts b/x-pack/plugins/alerting/server/rules_settings_client_factory.test.ts new file mode 100644 index 0000000000000..176082ee02336 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client_factory.test.ts @@ -0,0 +1,161 @@ +/* + * 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 { Request } from '@hapi/hapi'; +import { CoreKibanaRequest } from '@kbn/core/server'; +import { + RulesSettingsClientFactory, + RulesSettingsClientFactoryOpts, +} from './rules_settings_client_factory'; +import { + savedObjectsClientMock, + savedObjectsServiceMock, + loggingSystemMock, +} from '@kbn/core/server/mocks'; +import { AuthenticatedUser } from '@kbn/security-plugin/common/model'; +import { securityMock } from '@kbn/security-plugin/server/mocks'; +import { SECURITY_EXTENSION_ID } from '@kbn/core-saved-objects-server'; +import { RULES_SETTINGS_SAVED_OBJECT_TYPE } from '../common'; + +jest.mock('./rules_settings_client'); + +const savedObjectsClient = savedObjectsClientMock.create(); +const savedObjectsService = savedObjectsServiceMock.createInternalStartContract(); + +const securityPluginStart = securityMock.createStart(); + +const rulesSettingsClientFactoryParams: jest.Mocked = { + logger: loggingSystemMock.create().get(), + savedObjectsService, +}; + +const fakeRequest = { + app: {}, + headers: {}, + getBasePath: () => '', + path: '/', + route: { settings: {} }, + url: { + href: '/', + }, + raw: { + req: { + url: '/', + }, + }, + getSavedObjectsClient: () => savedObjectsClient, +} as unknown as Request; + +beforeEach(() => { + jest.resetAllMocks(); +}); + +test('creates a rules settings client with proper constructor arguments when security is enabled', async () => { + const factory = new RulesSettingsClientFactory(); + factory.initialize({ + securityPluginStart, + ...rulesSettingsClientFactoryParams, + }); + const request = CoreKibanaRequest.from(fakeRequest); + + savedObjectsService.getScopedClient.mockReturnValue(savedObjectsClient); + + factory.createWithAuthorization(request); + + expect(savedObjectsService.getScopedClient).toHaveBeenCalledWith(request, { + includedHiddenTypes: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + }); + + const { RulesSettingsClient } = jest.requireMock('./rules_settings_client'); + + expect(RulesSettingsClient).toHaveBeenCalledWith({ + logger: rulesSettingsClientFactoryParams.logger, + savedObjectsClient, + getUserName: expect.any(Function), + }); +}); + +test('creates a rules settings client with proper constructor arguments', async () => { + const factory = new RulesSettingsClientFactory(); + factory.initialize(rulesSettingsClientFactoryParams); + const request = CoreKibanaRequest.from(fakeRequest); + + savedObjectsService.getScopedClient.mockReturnValue(savedObjectsClient); + + factory.createWithAuthorization(request); + + expect(savedObjectsService.getScopedClient).toHaveBeenCalledWith(request, { + includedHiddenTypes: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + }); + + const { RulesSettingsClient } = jest.requireMock('./rules_settings_client'); + + expect(RulesSettingsClient).toHaveBeenCalledWith({ + logger: rulesSettingsClientFactoryParams.logger, + savedObjectsClient, + getUserName: expect.any(Function), + }); +}); + +test('creates an unauthorized rules settings client', async () => { + const factory = new RulesSettingsClientFactory(); + factory.initialize({ + securityPluginStart, + ...rulesSettingsClientFactoryParams, + }); + const request = CoreKibanaRequest.from(fakeRequest); + + savedObjectsService.getScopedClient.mockReturnValue(savedObjectsClient); + + factory.create(request); + + expect(savedObjectsService.getScopedClient).toHaveBeenCalledWith(request, { + excludedExtensions: [SECURITY_EXTENSION_ID], + includedHiddenTypes: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + }); + + const { RulesSettingsClient } = jest.requireMock('./rules_settings_client'); + + expect(RulesSettingsClient).toHaveBeenCalledWith({ + logger: rulesSettingsClientFactoryParams.logger, + savedObjectsClient, + getUserName: expect.any(Function), + }); +}); + +test('getUserName() returns null when security is disabled', async () => { + const factory = new RulesSettingsClientFactory(); + factory.initialize(rulesSettingsClientFactoryParams); + const request = CoreKibanaRequest.from(fakeRequest); + + factory.createWithAuthorization(request); + const constructorCall = + jest.requireMock('./rules_settings_client').RulesSettingsClient.mock.calls[0][0]; + + const userNameResult = await constructorCall.getUserName(); + expect(userNameResult).toEqual(null); +}); + +test('getUserName() returns a name when security is enabled', async () => { + const factory = new RulesSettingsClientFactory(); + factory.initialize({ + securityPluginStart, + ...rulesSettingsClientFactoryParams, + }); + const request = CoreKibanaRequest.from(fakeRequest); + + factory.createWithAuthorization(request); + + const constructorCall = + jest.requireMock('./rules_settings_client').RulesSettingsClient.mock.calls[0][0]; + + securityPluginStart.authc.getCurrentUser.mockReturnValueOnce({ + username: 'testname', + } as unknown as AuthenticatedUser); + const userNameResult = await constructorCall.getUserName(); + expect(userNameResult).toEqual('testname'); +}); diff --git a/x-pack/plugins/alerting/server/rules_settings_client_factory.ts b/x-pack/plugins/alerting/server/rules_settings_client_factory.ts new file mode 100644 index 0000000000000..619e498c6b988 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client_factory.ts @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + KibanaRequest, + Logger, + SavedObjectsServiceStart, + SECURITY_EXTENSION_ID, +} from '@kbn/core/server'; +import { SecurityPluginStart } from '@kbn/security-plugin/server'; +import { RulesSettingsClient } from './rules_settings_client'; +import { RULES_SETTINGS_SAVED_OBJECT_TYPE } from '../common'; + +export interface RulesSettingsClientFactoryOpts { + logger: Logger; + savedObjectsService: SavedObjectsServiceStart; + securityPluginStart?: SecurityPluginStart; +} + +export class RulesSettingsClientFactory { + private isInitialized = false; + private logger!: Logger; + private savedObjectsService!: SavedObjectsServiceStart; + private securityPluginStart?: SecurityPluginStart; + + public initialize(options: RulesSettingsClientFactoryOpts) { + if (this.isInitialized) { + throw new Error('RulesSettingsClientFactory already initialized'); + } + this.isInitialized = true; + this.logger = options.logger; + this.savedObjectsService = options.savedObjectsService; + this.securityPluginStart = options.securityPluginStart; + } + + private createRulesSettingsClient(request: KibanaRequest, withAuth: boolean) { + const { securityPluginStart } = this; + const savedObjectsClient = this.savedObjectsService.getScopedClient(request, { + includedHiddenTypes: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + ...(withAuth ? {} : { excludedExtensions: [SECURITY_EXTENSION_ID] }), + }); + + return new RulesSettingsClient({ + logger: this.logger, + savedObjectsClient, + async getUserName() { + if (!securityPluginStart || !request) { + return null; + } + const user = securityPluginStart.authc.getCurrentUser(request); + return user ? user.username : null; + }, + }); + } + + public createWithAuthorization(request: KibanaRequest) { + return this.createRulesSettingsClient(request, true); + } + + public create(request: KibanaRequest) { + return this.createRulesSettingsClient(request, false); + } +} diff --git a/x-pack/plugins/alerting/server/rules_settings_feature.ts b/x-pack/plugins/alerting/server/rules_settings_feature.ts new file mode 100644 index 0000000000000..c207d337a2b20 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_feature.ts @@ -0,0 +1,91 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { KibanaFeatureConfig } from '@kbn/features-plugin/common'; +import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; +import { + RULES_SETTINGS_FEATURE_ID, + READ_FLAPPING_SETTINGS_SUB_FEATURE_ID, + ALL_FLAPPING_SETTINGS_SUB_FEATURE_ID, + API_PRIVILEGES, + RULES_SETTINGS_SAVED_OBJECT_TYPE, +} from '../common'; + +export const rulesSettingsFeature: KibanaFeatureConfig = { + id: RULES_SETTINGS_FEATURE_ID, + name: i18n.translate('xpack.alerting.feature.rulesSettingsFeatureName', { + defaultMessage: 'Rules Settings', + }), + category: DEFAULT_APP_CATEGORIES.management, + app: [], + management: { + insightsAndAlerting: ['triggersActions'], + }, + privileges: { + all: { + app: [], + api: [], + management: { + insightsAndAlerting: ['triggersActions'], + }, + savedObject: { + all: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + read: [], + }, + ui: ['show', 'save'], + }, + read: { + app: [], + api: [], + management: { + insightsAndAlerting: ['triggersActions'], + }, + savedObject: { + all: [], + read: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + }, + ui: ['show'], + }, + }, + subFeatures: [ + { + name: i18n.translate('xpack.alerting.feature.flappingSettingsSubFeatureName', { + defaultMessage: 'Flapping Detection', + }), + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + api: [API_PRIVILEGES.READ_FLAPPING_SETTINGS, API_PRIVILEGES.WRITE_FLAPPING_SETTINGS], + name: 'All', + id: ALL_FLAPPING_SETTINGS_SUB_FEATURE_ID, + includeIn: 'all', + savedObject: { + all: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + read: [], + }, + ui: ['writeFlappingSettingsUI', 'readFlappingSettingsUI'], + }, + { + api: [API_PRIVILEGES.READ_FLAPPING_SETTINGS], + name: 'Read', + id: READ_FLAPPING_SETTINGS_SUB_FEATURE_ID, + includeIn: 'read', + savedObject: { + all: [], + read: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + }, + ui: ['readFlappingSettingsUI'], + }, + ], + }, + ], + }, + ], +}; diff --git a/x-pack/plugins/alerting/server/saved_objects/index.ts b/x-pack/plugins/alerting/server/saved_objects/index.ts index d8d53f4978d55..cd69efaf3e875 100644 --- a/x-pack/plugins/alerting/server/saved_objects/index.ts +++ b/x-pack/plugins/alerting/server/saved_objects/index.ts @@ -14,6 +14,7 @@ import type { import { EncryptedSavedObjectsPluginSetup } from '@kbn/encrypted-saved-objects-plugin/server'; import { MigrateFunctionsObject } from '@kbn/kibana-utils-plugin/common'; import { alertMappings } from './mappings'; +import { rulesSettingsMappings } from './rules_settings_mappings'; import { getMigrations } from './migrations'; import { transformRulesForExport } from './transform_rule_for_export'; import { RawRule } from '../types'; @@ -21,6 +22,7 @@ import { getImportWarnings } from './get_import_warnings'; import { isRuleExportable } from './is_rule_exportable'; import { RuleTypeRegistry } from '../rule_type_registry'; export { partiallyUpdateAlert } from './partially_update_alert'; +import { RULES_SETTINGS_SAVED_OBJECT_TYPE } from '../../common'; // Use caution when removing items from this array! Any field which has // ever existed in the rule SO must be included in this array to prevent @@ -114,6 +116,13 @@ export function setupSavedObjects( }, }); + savedObjects.registerType({ + name: RULES_SETTINGS_SAVED_OBJECT_TYPE, + hidden: true, + namespaceType: 'single', + mappings: rulesSettingsMappings, + }); + // Encrypted attributes encryptedSavedObjects.registerType({ type: 'alert', diff --git a/x-pack/plugins/alerting/server/saved_objects/rules_settings_mappings.ts b/x-pack/plugins/alerting/server/saved_objects/rules_settings_mappings.ts new file mode 100644 index 0000000000000..d20567edc2832 --- /dev/null +++ b/x-pack/plugins/alerting/server/saved_objects/rules_settings_mappings.ts @@ -0,0 +1,45 @@ +/* + * 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 { SavedObjectsTypeMappingDefinition } from '@kbn/core/server'; + +export const rulesSettingsMappings: SavedObjectsTypeMappingDefinition = { + properties: { + flapping: { + properties: { + enabled: { + type: 'boolean', + index: false, + }, + lookBackWindow: { + type: 'long', + index: false, + }, + statusChangeThreshold: { + type: 'long', + index: false, + }, + createdBy: { + type: 'keyword', + index: false, + }, + updatedBy: { + type: 'keyword', + index: false, + }, + createdAt: { + type: 'date', + index: false, + }, + updatedAt: { + type: 'date', + index: false, + }, + }, + }, + }, +}; diff --git a/x-pack/plugins/alerting/server/types.ts b/x-pack/plugins/alerting/server/types.ts index c0399779a62df..f2a368c062d05 100644 --- a/x-pack/plugins/alerting/server/types.ts +++ b/x-pack/plugins/alerting/server/types.ts @@ -25,6 +25,7 @@ import { SharePluginStart } from '@kbn/share-plugin/server'; import { RuleTypeRegistry as OrigruleTypeRegistry } from './rule_type_registry'; import { PluginSetupContract, PluginStartContract } from './plugin'; import { RulesClient } from './rules_client'; +import { RulesSettingsClient, RulesSettingsFlappingClient } from './rules_settings_client'; export * from '../common'; import { Rule, @@ -57,6 +58,7 @@ export type { RuleTypeParams }; */ export interface AlertingApiRequestHandlerContext { getRulesClient: () => RulesClient; + getRulesSettingsClient: () => RulesSettingsClient; listTypes: RuleTypeRegistry['list']; getFrameworkHealth: () => Promise; areApiKeysEnabled: () => Promise; @@ -320,6 +322,9 @@ export type RuleTypeRegistry = PublicMethodsOf; export type RulesClientApi = PublicMethodsOf; +export type RulesSettingsClientApi = PublicMethodsOf; +export type RulesSettingsFlappingClientApi = PublicMethodsOf; + export interface PublicMetricsSetters { setLastRunMetricsTotalSearchDurationMs: (totalSearchDurationMs: number) => void; setLastRunMetricsTotalIndexingDurationMs: (totalIndexingDurationMs: number) => void; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_flapping_form_section.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_flapping_form_section.tsx new file mode 100644 index 0000000000000..bfde62591f626 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_flapping_form_section.tsx @@ -0,0 +1,213 @@ +/* + * 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 React, { memo } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiFormRowProps, + EuiIconTip, + EuiRange, + EuiRangeProps, + EuiSpacer, + EuiTitle, + EuiText, + EuiPanel, +} from '@elastic/eui'; +import { + RulesSettingsFlappingProperties, + MIN_LOOK_BACK_WINDOW, + MIN_STATUS_CHANGE_THRESHOLD, + MAX_LOOK_BACK_WINDOW, + MAX_STATUS_CHANGE_THRESHOLD, +} from '@kbn/alerting-plugin/common'; +import { useKibana } from '../../../common/lib/kibana'; + +type OnChangeKey = keyof Omit; + +const lookBackWindowLabel = i18n.translate( + 'xpack.triggersActionsUI.rulesSettings.flapping.lookBackWindowLabel', + { + defaultMessage: 'Rule run look back window', + } +); + +const statusChangeThresholdLabel = i18n.translate( + 'xpack.triggersActionsUI.rulesSettings.flapping.statusChangeThresholdLabel', + { + defaultMessage: 'Alert status change threshold', + } +); + +const getLookBackWindowLabelRuleRuns = (amount: number) => { + return i18n.translate( + 'xpack.triggersActionsUI.rulesSettings.flapping.lookBackWindowLabelRuleRuns', + { + defaultMessage: '{amount, number} rule {amount, plural, one {run} other {runs}}', + values: { amount }, + } + ); +}; + +const getStatusChangeThresholdRuleRuns = (amount: number) => { + return i18n.translate( + 'xpack.triggersActionsUI.rulesSettings.flapping.statusChangeThresholdTimes', + { + defaultMessage: '{amount, number} {amount, plural, one {time} other {times}}', + values: { amount }, + } + ); +}; + +export interface RulesSettingsRangeProps { + label: EuiFormRowProps['label']; + labelPopoverText?: string; + min: number; + max: number; + value: number; + disabled?: EuiRangeProps['disabled']; + onChange?: EuiRangeProps['onChange']; +} + +export const RulesSettingsFlappingTitle = () => { + return ( + +
    + +
    +
    + ); +}; + +export const RulesSettingsFlappingDescription = () => { + return ( + + + + ); +}; + +export const RulesSettingsRange = memo((props: RulesSettingsRangeProps) => { + const { label, labelPopoverText, min, max, value, disabled, onChange, ...rest } = props; + + const renderLabel = () => { + return ( +
    + {label} +   + +
    + ); + }; + + return ( + + + + ); +}); + +export interface RulesSettingsFlappingFormSectionProps { + flappingSettings: RulesSettingsFlappingProperties; + compressed?: boolean; + onChange: (key: OnChangeKey, value: number) => void; +} + +export const RulesSettingsFlappingFormSection = memo( + (props: RulesSettingsFlappingFormSectionProps) => { + const { flappingSettings, compressed = false, onChange } = props; + + const { lookBackWindow, statusChangeThreshold } = flappingSettings; + + const { + application: { capabilities }, + } = useKibana().services; + + const { + rulesSettings: { writeFlappingSettingsUI }, + } = capabilities; + + const canWriteFlappingSettings = writeFlappingSettingsUI; + + return ( + + {compressed && ( + <> + + + + + + + + + + + + + )} + + onChange('lookBackWindow', parseInt(e.currentTarget.value, 10))} + label={lookBackWindowLabel} + disabled={!canWriteFlappingSettings} + /> + + + onChange('statusChangeThreshold', parseInt(e.currentTarget.value, 10))} + label={statusChangeThresholdLabel} + disabled={!canWriteFlappingSettings} + /> + + + + + {getLookBackWindowLabelRuleRuns(lookBackWindow)}, + statusChangeThreshold: ( + {getStatusChangeThresholdRuleRuns(statusChangeThreshold)} + ), + }} + /> + + + + + ); + } +); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_link.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_link.test.tsx new file mode 100644 index 0000000000000..e2e454e644ac0 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_link.test.tsx @@ -0,0 +1,150 @@ +/* + * 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 React from 'react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; +import { render, cleanup, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { coreMock } from '@kbn/core/public/mocks'; +import { RulesSettingsFlapping } from '@kbn/alerting-plugin/common'; +import { RulesSettingsLink } from './rules_settings_link'; +import { useKibana } from '../../../common/lib/kibana'; +import { getFlappingSettings } from '../../lib/rule_api'; +import { updateFlappingSettings } from '../../lib/rule_api'; + +jest.mock('../../../common/lib/kibana'); +jest.mock('../../lib/rule_api/get_flapping_settings', () => ({ + getFlappingSettings: jest.fn(), +})); +jest.mock('../../lib/rule_api/update_flapping_settings', () => ({ + updateFlappingSettings: jest.fn(), +})); + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + cacheTime: 0, + }, + }, +}); + +const useKibanaMock = useKibana as jest.Mocked; + +const mocks = coreMock.createSetup(); + +const getFlappingSettingsMock = getFlappingSettings as unknown as jest.MockedFunction< + typeof getFlappingSettings +>; +const updateFlappingSettingsMock = updateFlappingSettings as unknown as jest.MockedFunction< + typeof updateFlappingSettings +>; + +const mockFlappingSetting: RulesSettingsFlapping = { + enabled: true, + lookBackWindow: 10, + statusChangeThreshold: 11, + createdBy: 'test user', + updatedBy: 'test user', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), +}; + +const RulesSettingsLinkWithProviders: React.FunctionComponent<{}> = () => ( + + + + + +); + +describe('rules_settings_link', () => { + beforeEach(async () => { + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + useKibanaMock().services.application.capabilities = { + ...capabilities, + rulesSettings: { + save: true, + show: true, + writeFlappingSettingsUI: true, + readFlappingSettingsUI: true, + }, + }; + getFlappingSettingsMock.mockResolvedValue(mockFlappingSetting); + updateFlappingSettingsMock.mockResolvedValue(mockFlappingSetting); + }); + + afterEach(() => { + jest.clearAllMocks(); + queryClient.clear(); + cleanup(); + }); + + test('renders the rules setting link correctly', async () => { + const result = render(); + await waitFor(() => { + expect(result.getByText('Settings')).toBeInTheDocument(); + }); + expect(result.getByText('Settings')).not.toBeDisabled(); + expect(result.queryByTestId('rulesSettingsModal')).toBe(null); + }); + + test('clicking the settings link opens the rules settings modal', async () => { + const result = render(); + await waitFor(() => { + expect(result.queryByTestId('rulesSettingsModal')).toBe(null); + }); + + userEvent.click(result.getByText('Settings')); + + await waitFor(() => { + expect(result.queryByTestId('rulesSettingsModal')).not.toBe(null); + }); + }); + + test('link is hidden when provided with insufficient read permissions', async () => { + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + useKibanaMock().services.application.capabilities = { + ...capabilities, + rulesSettings: { + save: true, + show: false, + writeFlappingSettingsUI: true, + readFlappingSettingsUI: true, + }, + }; + + let result = render(); + await waitFor(() => { + expect(result.queryByTestId('rulesSettingsLink')).toBe(null); + }); + + useKibanaMock().services.application.capabilities = { + ...capabilities, + rulesSettings: { + save: true, + show: true, + writeFlappingSettingsUI: true, + readFlappingSettingsUI: false, + }, + }; + + result = render(); + await waitFor(() => { + expect(result.queryByTestId('rulesSettingsLink')).toBe(null); + }); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_link.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_link.tsx new file mode 100644 index 0000000000000..bb72db2bc4163 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_link.tsx @@ -0,0 +1,41 @@ +/* + * 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 React, { useState } from 'react'; +import { EuiButtonEmpty } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { RulesSettingsModal } from './rules_settings_modal'; +import { useKibana } from '../../../common/lib/kibana'; + +export const RulesSettingsLink = () => { + const [isVisible, setIsVisible] = useState(false); + const { + application: { capabilities }, + } = useKibana().services; + + const { show, readFlappingSettingsUI } = capabilities.rulesSettings; + + if (!show || !readFlappingSettingsUI) { + return null; + } + + return ( + <> + setIsVisible(true)} + iconType="gear" + data-test-subj="rulesSettingsLink" + > + + + setIsVisible(false)} /> + + ); +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_modal.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_modal.test.tsx new file mode 100644 index 0000000000000..6915a46123a40 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_modal.test.tsx @@ -0,0 +1,264 @@ +/* + * 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 React from 'react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; +import { render, fireEvent, cleanup, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { coreMock } from '@kbn/core/public/mocks'; +import { IToasts } from '@kbn/core/public'; +import { RulesSettingsFlapping } from '@kbn/alerting-plugin/common'; +import { RulesSettingsModal, RulesSettingsModalProps } from './rules_settings_modal'; +import { useKibana } from '../../../common/lib/kibana'; +import { getFlappingSettings } from '../../lib/rule_api/get_flapping_settings'; +import { updateFlappingSettings } from '../../lib/rule_api/update_flapping_settings'; + +jest.mock('../../../common/lib/kibana'); +jest.mock('../../lib/rule_api/get_flapping_settings', () => ({ + getFlappingSettings: jest.fn(), +})); +jest.mock('../../lib/rule_api/update_flapping_settings', () => ({ + updateFlappingSettings: jest.fn(), +})); + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + cacheTime: 0, + }, + }, +}); + +const useKibanaMock = useKibana as jest.Mocked; + +const mocks = coreMock.createSetup(); + +const getFlappingSettingsMock = getFlappingSettings as unknown as jest.MockedFunction< + typeof getFlappingSettings +>; +const updateFlappingSettingsMock = updateFlappingSettings as unknown as jest.MockedFunction< + typeof updateFlappingSettings +>; + +const mockFlappingSetting: RulesSettingsFlapping = { + enabled: true, + lookBackWindow: 10, + statusChangeThreshold: 10, + createdBy: 'test user', + updatedBy: 'test user', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), +}; + +const modalProps: RulesSettingsModalProps = { + isVisible: true, + setUpdatingRulesSettings: jest.fn(), + onClose: jest.fn(), + onSave: jest.fn(), +}; + +const RulesSettingsModalWithProviders: React.FunctionComponent = ( + props +) => ( + + + + + +); + +describe('rules_settings_modal', () => { + beforeEach(async () => { + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + useKibanaMock().services.application.capabilities = { + ...capabilities, + rulesSettings: { + save: true, + show: true, + writeFlappingSettingsUI: true, + readFlappingSettingsUI: true, + }, + }; + + useKibanaMock().services.notifications.toasts = { + addSuccess: jest.fn(), + addError: jest.fn(), + addDanger: jest.fn(), + addWarning: jest.fn(), + } as unknown as IToasts; + + getFlappingSettingsMock.mockResolvedValue(mockFlappingSetting); + updateFlappingSettingsMock.mockResolvedValue(mockFlappingSetting); + }); + + afterEach(() => { + jest.clearAllMocks(); + queryClient.clear(); + cleanup(); + }); + + test('renders flapping settings correctly', async () => { + const result = render(); + expect(getFlappingSettingsMock).toHaveBeenCalledTimes(1); + await waitFor(() => { + expect(result.queryByTestId('centerJustifiedSpinner')).toBe(null); + }); + expect(result.getByTestId('rulesSettingsModalEnableSwitch').getAttribute('aria-checked')).toBe( + 'true' + ); + expect(result.getByTestId('lookBackWindowRangeInput').getAttribute('value')).toBe('10'); + expect(result.getByTestId('statusChangeThresholdRangeInput').getAttribute('value')).toBe('10'); + + expect(result.getByTestId('rulesSettingsModalCancelButton')).toBeInTheDocument(); + expect(result.getByTestId('rulesSettingsModalSaveButton').getAttribute('disabled')).toBeFalsy(); + }); + + test('can save flapping settings', async () => { + const result = render(); + await waitFor(() => { + expect(result.queryByTestId('centerJustifiedSpinner')).toBe(null); + }); + + const lookBackWindowInput = result.getByTestId('lookBackWindowRangeInput'); + const statusChangeThresholdInput = result.getByTestId('statusChangeThresholdRangeInput'); + + fireEvent.change(lookBackWindowInput, { target: { value: 20 } }); + fireEvent.change(statusChangeThresholdInput, { target: { value: 5 } }); + + expect(lookBackWindowInput.getAttribute('value')).toBe('20'); + expect(statusChangeThresholdInput.getAttribute('value')).toBe('5'); + + // Try saving + userEvent.click(result.getByTestId('rulesSettingsModalSaveButton')); + + await waitFor(() => { + expect(modalProps.setUpdatingRulesSettings).toHaveBeenCalledWith(true); + }); + expect(modalProps.onClose).toHaveBeenCalledTimes(1); + expect(updateFlappingSettingsMock).toHaveBeenCalledWith( + expect.objectContaining({ + flappingSettings: { + enabled: true, + lookBackWindow: 20, + statusChangeThreshold: 5, + }, + }) + ); + expect(useKibanaMock().services.notifications.toasts.addSuccess).toHaveBeenCalledTimes(1); + expect(modalProps.setUpdatingRulesSettings).toHaveBeenCalledWith(true); + expect(modalProps.onSave).toHaveBeenCalledTimes(1); + }); + + test('should prevent statusChangeThreshold from being greater than lookBackWindow', async () => { + const result = render(); + await waitFor(() => { + expect(result.queryByTestId('centerJustifiedSpinner')).toBe(null); + }); + + const lookBackWindowInput = result.getByTestId('lookBackWindowRangeInput'); + const statusChangeThresholdInput = result.getByTestId('statusChangeThresholdRangeInput'); + + // Change lookBackWindow to a smaller value + fireEvent.change(lookBackWindowInput, { target: { value: 5 } }); + // statusChangeThresholdInput gets pinned to be 5 + expect(statusChangeThresholdInput.getAttribute('value')).toBe('5'); + + // Try making statusChangeThreshold bigger + fireEvent.change(statusChangeThresholdInput, { target: { value: 20 } }); + // Still pinned + expect(statusChangeThresholdInput.getAttribute('value')).toBe('5'); + + fireEvent.change(statusChangeThresholdInput, { target: { value: 3 } }); + expect(statusChangeThresholdInput.getAttribute('value')).toBe('3'); + }); + + test('handles errors when saving settings', async () => { + updateFlappingSettingsMock.mockRejectedValue('failed!'); + + const result = render(); + await waitFor(() => { + expect(result.queryByTestId('centerJustifiedSpinner')).toBe(null); + }); + + // Try saving + userEvent.click(result.getByTestId('rulesSettingsModalSaveButton')); + await waitFor(() => { + expect(modalProps.setUpdatingRulesSettings).toHaveBeenCalledWith(true); + }); + expect(modalProps.onClose).toHaveBeenCalledTimes(1); + expect(useKibanaMock().services.notifications.toasts.addDanger).toHaveBeenCalledTimes(1); + expect(modalProps.setUpdatingRulesSettings).toHaveBeenCalledWith(true); + expect(modalProps.onSave).toHaveBeenCalledTimes(1); + }); + + test('displays flapping detection off prompt when flapping is disabled', async () => { + const result = render(); + await waitFor(() => { + expect(result.queryByTestId('centerJustifiedSpinner')).toBe(null); + }); + + expect(result.queryByTestId('rulesSettingsModalFlappingOffPrompt')).toBe(null); + userEvent.click(result.getByTestId('rulesSettingsModalEnableSwitch')); + expect(result.queryByTestId('rulesSettingsModalFlappingOffPrompt')).not.toBe(null); + }); + + test('form elements are disabled when provided with insufficient write permissions', async () => { + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + useKibanaMock().services.application.capabilities = { + ...capabilities, + rulesSettings: { + save: true, + show: true, + writeFlappingSettingsUI: false, + readFlappingSettingsUI: true, + }, + }; + const result = render(); + await waitFor(() => { + expect(result.queryByTestId('centerJustifiedSpinner')).toBe(null); + }); + + expect(result.getByTestId('rulesSettingsModalEnableSwitch')).toBeDisabled(); + expect(result.getByTestId('lookBackWindowRangeInput')).toBeDisabled(); + expect(result.getByTestId('statusChangeThresholdRangeInput')).toBeDisabled(); + expect(result.getByTestId('rulesSettingsModalSaveButton')).toBeDisabled(); + }); + + test('form elements are not visible when provided with insufficient read permissions', async () => { + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + useKibanaMock().services.application.capabilities = { + ...capabilities, + rulesSettings: { + save: true, + show: false, + writeFlappingSettingsUI: true, + readFlappingSettingsUI: false, + }, + }; + + const result = render(); + await waitFor(() => { + expect(result.queryByTestId('centerJustifiedSpinner')).toBe(null); + }); + + expect(result.getByTestId('rulesSettingsErrorPrompt')).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_modal.tsx new file mode 100644 index 0000000000000..3b9e5d9ecf0ae --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_modal.tsx @@ -0,0 +1,299 @@ +/* + * 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 React, { memo, useState } from 'react'; +import { RulesSettingsFlappingProperties } from '@kbn/alerting-plugin/common'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiButton, + EuiButtonEmpty, + EuiCallOut, + EuiHorizontalRule, + EuiFlexGroup, + EuiFlexItem, + EuiForm, + EuiModal, + EuiModalHeader, + EuiModalBody, + EuiModalFooter, + EuiModalHeaderTitle, + EuiSpacer, + EuiSwitch, + EuiSwitchProps, + EuiPanel, + EuiText, + EuiEmptyPrompt, +} from '@elastic/eui'; +import { useKibana } from '../../../common/lib/kibana'; +import { + RulesSettingsFlappingFormSection, + RulesSettingsFlappingFormSectionProps, + RulesSettingsFlappingTitle, +} from './rules_settings_flapping_form_section'; +import { useGetFlappingSettings } from '../../hooks/use_get_flapping_settings'; +import { useUpdateFlappingSettings } from '../../hooks/use_update_flapping_settings'; +import { CenterJustifiedSpinner } from '../center_justified_spinner'; + +const flappingDescription = i18n.translate( + 'xpack.triggersActionsUI.rulesSettings.modal.flappingDetectionDescription', + { + defaultMessage: + 'Alerts that go quickly go between active and recovered are considered flapping. Detecting these changes and minimizing new alert generation can help reduce unwanted noise in your alerting system.', + } +); + +const flappingEnableLabel = i18n.translate( + 'xpack.triggersActionsUI.rulesSettings.modal.enableFlappingLabel', + { + defaultMessage: 'Enabled flapping detection (recommended)', + } +); + +export const RulesSettingsErrorPrompt = memo(() => { + return ( + + + + } + body={ +

    + +

    + } + /> + ); +}); + +interface RulesSettingsModalFormLeftProps { + settings: RulesSettingsFlappingProperties; + onChange: EuiSwitchProps['onChange']; + isSwitchDisabled: boolean; +} + +export const RulesSettingsModalFormLeft = memo((props: RulesSettingsModalFormLeftProps) => { + const { settings, onChange, isSwitchDisabled } = props; + + return ( + + + + +

    {flappingDescription}

    +
    +
    + + + +
    +
    + ); +}); + +interface RulesSettingsModalFormRightProps { + settings: RulesSettingsFlappingProperties; + onChange: RulesSettingsFlappingFormSectionProps['onChange']; +} + +export const RulesSettingsModalFormRight = memo((props: RulesSettingsModalFormRightProps) => { + const { settings, onChange } = props; + + if (!settings) { + return null; + } + if (!settings.enabled) { + return ( + + + + + + + + ); + } + + return ( + + + + ); +}); + +export interface RulesSettingsModalProps { + isVisible: boolean; + setUpdatingRulesSettings?: (isUpdating: boolean) => void; + onClose: () => void; + onSave?: () => void; +} + +export const RulesSettingsModal = memo((props: RulesSettingsModalProps) => { + const { isVisible, onClose, setUpdatingRulesSettings, onSave } = props; + + const { + application: { capabilities }, + } = useKibana().services; + const { + rulesSettings: { show, save, writeFlappingSettingsUI, readFlappingSettingsUI }, + } = capabilities; + + const [settings, setSettings] = useState(); + + const { isLoading, isError: hasError } = useGetFlappingSettings({ + enabled: isVisible, + onSuccess: (fetchedSettings) => { + if (!settings) { + setSettings({ + enabled: fetchedSettings.enabled, + lookBackWindow: fetchedSettings.lookBackWindow, + statusChangeThreshold: fetchedSettings.statusChangeThreshold, + }); + } + }, + }); + + const { mutate } = useUpdateFlappingSettings({ + onSave, + onClose, + setUpdatingRulesSettings, + }); + + // In the future when we have more settings sub-features, we should + // disassociate the rule settings capabilities (save, show) from the + // sub-feature capabilities (writeXSettingsUI). + const canWriteFlappingSettings = save && writeFlappingSettingsUI && !hasError; + const canShowFlappingSettings = show && readFlappingSettingsUI; + + const handleSettingsChange = ( + key: keyof RulesSettingsFlappingProperties, + value: number | boolean + ) => { + if (!settings) { + return; + } + + const newSettings = { + ...settings, + [key]: value, + }; + + setSettings({ + ...newSettings, + statusChangeThreshold: Math.min( + newSettings.lookBackWindow, + newSettings.statusChangeThreshold + ), + }); + }; + + const handleSave = () => { + if (!settings) { + return; + } + mutate(settings); + }; + + if (!isVisible) { + return null; + } + + const maybeRenderForm = () => { + if (hasError || !canShowFlappingSettings) { + return ; + } + if (!settings || isLoading) { + return ; + } + return ( + + + + + + + + + handleSettingsChange('enabled', e.target.checked)} + /> + handleSettingsChange(key, value)} + /> + + + ); + }; + + return ( + + + +

    + +

    +
    +
    + + + + {maybeRenderForm()} + + + + + + + + + + + +
    + ); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_get_flapping_settings.ts b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_get_flapping_settings.ts new file mode 100644 index 0000000000000..23f4af9e9daa7 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_get_flapping_settings.ts @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { useQuery } from '@tanstack/react-query'; +import { RulesSettingsFlapping } from '@kbn/alerting-plugin/common'; +import { useKibana } from '../../common/lib/kibana'; +import { getFlappingSettings } from '../lib/rule_api'; + +interface UseGetFlappingSettingsProps { + enabled: boolean; + onSuccess: (settings: RulesSettingsFlapping) => void; +} + +export const useGetFlappingSettings = (props: UseGetFlappingSettingsProps) => { + const { enabled, onSuccess } = props; + const { + http, + notifications: { toasts }, + } = useKibana().services; + + const queryFn = () => { + return getFlappingSettings({ http }); + }; + + const onErrorFn = () => { + toasts.addDanger( + i18n.translate('xpack.triggersActionsUI.rulesSettings.modal.getRulesSettingsError', { + defaultMessage: 'Failed to get rules Settings.', + }) + ); + }; + + const { data, isFetching, isError, isLoadingError, isLoading } = useQuery({ + queryKey: ['getFlappingSettings'], + queryFn, + onError: onErrorFn, + onSuccess, + enabled, + refetchOnWindowFocus: false, + retry: false, + }); + + return { + isLoading: isLoading || isFetching, + isError: isError || isLoadingError, + data, + }; +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_update_flapping_settings.ts b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_update_flapping_settings.ts new file mode 100644 index 0000000000000..d5f978db9d3c0 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_update_flapping_settings.ts @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { useMutation } from '@tanstack/react-query'; +import { RulesSettingsFlappingProperties } from '@kbn/alerting-plugin/common'; +import { useKibana } from '../../common/lib/kibana'; +import { updateFlappingSettings } from '../lib/rule_api'; + +interface UseUpdateFlappingSettingsProps { + onClose: () => void; + onSave?: () => void; + setUpdatingRulesSettings?: (isUpdating: boolean) => void; +} + +export const useUpdateFlappingSettings = (props: UseUpdateFlappingSettingsProps) => { + const { onSave, onClose, setUpdatingRulesSettings } = props; + + const { + http, + notifications: { toasts }, + } = useKibana().services; + + const mutationFn = (flappingSettings: RulesSettingsFlappingProperties) => { + return updateFlappingSettings({ http, flappingSettings }); + }; + + return useMutation({ + mutationFn, + onMutate: () => { + onClose(); + setUpdatingRulesSettings?.(true); + }, + onSuccess: () => { + toasts.addSuccess( + i18n.translate('xpack.triggersActionsUI.rulesSettings.modal.updateRulesSettingsSuccess', { + defaultMessage: 'Rules settings updated successfully.', + }) + ); + }, + onError: () => { + toasts.addDanger( + i18n.translate('xpack.triggersActionsUI.rulesSettings.modal.updateRulesSettingsFailure', { + defaultMessage: 'Failed to update rules settings.', + }) + ); + }, + onSettled: () => { + setUpdatingRulesSettings?.(false); + onSave?.(); + }, + }); +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/get_flapping_settings.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/get_flapping_settings.ts new file mode 100644 index 0000000000000..68947de984fb4 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/get_flapping_settings.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. + */ + +import { HttpSetup } from '@kbn/core/public'; +import { RulesSettingsFlapping } from '@kbn/alerting-plugin/common'; +import { INTERNAL_BASE_ALERTING_API_PATH } from '../../constants'; + +export const getFlappingSettings = ({ http }: { http: HttpSetup }) => { + return http.get( + `${INTERNAL_BASE_ALERTING_API_PATH}/rules/settings/_flapping` + ); +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/index.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/index.ts index f1d65768802ec..74157ac200ce7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/index.ts @@ -46,3 +46,5 @@ export { runSoon } from './run_soon'; export { bulkDeleteRules } from './bulk_delete'; export { bulkEnableRules } from './bulk_enable'; export { bulkDisableRules } from './bulk_disable'; +export { getFlappingSettings } from './get_flapping_settings'; +export { updateFlappingSettings } from './update_flapping_settings'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update_flapping_settings.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update_flapping_settings.ts new file mode 100644 index 0000000000000..f38393b591d72 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update_flapping_settings.ts @@ -0,0 +1,34 @@ +/* + * 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 { HttpSetup } from '@kbn/core/public'; +import { + RulesSettingsFlapping, + RulesSettingsFlappingProperties, +} from '@kbn/alerting-plugin/common'; +import { INTERNAL_BASE_ALERTING_API_PATH } from '../../constants'; + +export const updateFlappingSettings = ({ + http, + flappingSettings, +}: { + http: HttpSetup; + flappingSettings: RulesSettingsFlappingProperties; +}) => { + let body: string; + try { + body = JSON.stringify(flappingSettings); + } catch (e) { + throw new Error(`Unable to parse flapping settings update params: ${e}`); + } + return http.post( + `${INTERNAL_BASE_ALERTING_API_PATH}/rules/settings/_flapping`, + { + body, + } + ); +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx index d87a1d4f3a831..360d54c6e4bf0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx @@ -97,6 +97,7 @@ import { MULTIPLE_RULE_TITLE, } from '../translations'; import { useBulkOperationToast } from '../../../hooks/use_bulk_operation_toast'; +import { RulesSettingsLink } from '../../../components/rules_setting/rules_settings_link'; import { useRulesListUiState as useUiState } from '../../../hooks/use_rules_list_ui_state'; // Directly lazy import the flyouts because the suspendedComponentWithProps component @@ -614,11 +615,15 @@ export const RulesList = ({ if (!setHeaderActions) return; if (showHeaderWithoutCreateButton) { - setHeaderActions([]); + setHeaderActions([, ]); return; } if (showHeaderWithCreateButton) { - setHeaderActions([, ]); + setHeaderActions([ + , + , + , + ]); return; } setHeaderActions(); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/get_flapping_settings.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/get_flapping_settings.ts new file mode 100644 index 0000000000000..80e0a3e4a5986 --- /dev/null +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/get_flapping_settings.ts @@ -0,0 +1,60 @@ +/* + * 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 expect from '@kbn/expect'; +import { DEFAULT_FLAPPING_SETTINGS } from '@kbn/alerting-plugin/common'; +import { UserAtSpaceScenarios } from '../../../scenarios'; +import { getUrlPrefix } from '../../../../common/lib'; +import { FtrProviderContext } from '../../../../common/ftr_provider_context'; + +// eslint-disable-next-line import/no-default-export +export default function getFlappingSettingsTests({ getService }: FtrProviderContext) { + const supertestWithoutAuth = getService('supertestWithoutAuth'); + + describe('getFlappingSettings', () => { + for (const scenario of UserAtSpaceScenarios) { + const { user, space } = scenario; + describe(scenario.id, () => { + it('should handle get flapping settings request appropriately', async () => { + const response = await supertestWithoutAuth + .get(`${getUrlPrefix(space.id)}/internal/alerting/rules/settings/_flapping`) + .auth(user.username, user.password); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'space_1_all at space2': + case 'space_1_all_with_restricted_fixture at space1': + case 'space_1_all_alerts_none_actions at space1': + expect(response.statusCode).to.eql(403); + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Forbidden', + statusCode: 403, + }); + break; + case 'global_read at space1': + case 'superuser at space1': + case 'space_1_all at space1': + expect(response.statusCode).to.eql(200); + expect(response.body.enabled).to.eql(DEFAULT_FLAPPING_SETTINGS.enabled); + expect(response.body.lookBackWindow).to.eql(DEFAULT_FLAPPING_SETTINGS.lookBackWindow); + expect(response.body.statusChangeThreshold).to.eql( + DEFAULT_FLAPPING_SETTINGS.statusChangeThreshold + ); + expect(response.body.createdBy).to.be.a('string'); + expect(response.body.updatedBy).to.be.a('string'); + expect(Date.parse(response.body.createdAt)).to.be.greaterThan(0); + expect(Date.parse(response.body.updatedAt)).to.be.greaterThan(0); + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); + }); + } + }); +} diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/index.ts index 0dd1ec2531733..0c6b4f815c9dc 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/index.ts @@ -25,6 +25,8 @@ export default function alertingTests({ loadTestFile, getService }: FtrProviderC loadTestFile(require.resolve('./bulk_enable')); loadTestFile(require.resolve('./bulk_disable')); loadTestFile(require.resolve('./clone')); + loadTestFile(require.resolve('./get_flapping_settings')); + loadTestFile(require.resolve('./update_flapping_settings')); }); }); } diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/update_flapping_settings.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/update_flapping_settings.ts new file mode 100644 index 0000000000000..29c82ee5e642e --- /dev/null +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/update_flapping_settings.ts @@ -0,0 +1,154 @@ +/* + * 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 expect from '@kbn/expect'; +import { DEFAULT_FLAPPING_SETTINGS } from '@kbn/alerting-plugin/common'; +import { UserAtSpaceScenarios, Superuser } from '../../../scenarios'; +import { getUrlPrefix } from '../../../../common/lib'; +import { FtrProviderContext } from '../../../../common/ftr_provider_context'; + +const resetRulesSettings = (supertestWithoutAuth: any, space: string) => { + return supertestWithoutAuth + .post(`${getUrlPrefix(space)}/internal/alerting/rules/settings/_flapping`) + .set('kbn-xsrf', 'foo') + .auth(Superuser.username, Superuser.password) + .send(DEFAULT_FLAPPING_SETTINGS); +}; + +// eslint-disable-next-line import/no-default-export +export default function updateFlappingSettingsTest({ getService }: FtrProviderContext) { + const supertestWithoutAuth = getService('supertestWithoutAuth'); + + describe('updateFlappingSettings', () => { + afterEach(async () => { + await resetRulesSettings(supertestWithoutAuth, 'space1'); + await resetRulesSettings(supertestWithoutAuth, 'space2'); + }); + + for (const scenario of UserAtSpaceScenarios) { + const { user, space } = scenario; + describe(scenario.id, () => { + it('should handle update flapping settings request appropriately', async () => { + const response = await supertestWithoutAuth + .post(`${getUrlPrefix(space.id)}/internal/alerting/rules/settings/_flapping`) + .set('kbn-xsrf', 'foo') + .auth(user.username, user.password) + .send({ + enabled: false, + lookBackWindow: 20, + statusChangeThreshold: 20, + }); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'global_read at space1': + case 'space_1_all at space2': + case 'space_1_all_with_restricted_fixture at space1': + case 'space_1_all_alerts_none_actions at space1': + expect(response.statusCode).to.eql(403); + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Forbidden', + statusCode: 403, + }); + break; + case 'superuser at space1': + case 'space_1_all at space1': + expect(response.statusCode).to.eql(200); + expect(response.body.enabled).to.eql(false); + expect(response.body.lookBackWindow).to.eql(20); + expect(response.body.statusChangeThreshold).to.eql(20); + expect(response.body.createdBy).to.eql(user.username); + expect(response.body.updatedBy).to.eql(user.username); + expect(Date.parse(response.body.createdAt)).to.be.greaterThan(0); + expect(Date.parse(response.body.updatedAt)).to.be.greaterThan(0); + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); + }); + } + + it('should error if provided with invalid inputs', async () => { + let response = await supertestWithoutAuth + .post(`${getUrlPrefix('space1')}/internal/alerting/rules/settings/_flapping`) + .set('kbn-xsrf', 'foo') + .auth(Superuser.username, Superuser.password) + .send({ + enabled: true, + lookBackWindow: 200, + statusChangeThreshold: 200, + }) + .expect(400); + + expect(response.body.message).to.eql( + 'Invalid lookBackWindow value, must be between 2 and 20, but got: 200.' + ); + + response = await supertestWithoutAuth + .post(`${getUrlPrefix('space1')}/internal/alerting/rules/settings/_flapping`) + .set('kbn-xsrf', 'foo') + .auth(Superuser.username, Superuser.password) + .send({ + enabled: true, + lookBackWindow: 20, + statusChangeThreshold: 200, + }) + .expect(400); + + expect(response.body.message).to.eql( + 'Invalid statusChangeThreshold value, must be between 2 and 20, but got: 200.' + ); + + response = await supertestWithoutAuth + .post(`${getUrlPrefix('space1')}/internal/alerting/rules/settings/_flapping`) + .set('kbn-xsrf', 'foo') + .auth(Superuser.username, Superuser.password) + .send({ + enabled: true, + lookBackWindow: 5, + statusChangeThreshold: 10, + }) + .expect(400); + + expect(response.body.message).to.eql( + 'Invalid values,lookBackWindow (5) must be equal to or greater than statusChangeThreshold (10).' + ); + }); + + describe('updateFlappingSettings for other spaces', () => { + it('should update specific isolated settings depending on space', async () => { + // Update the rules setting in space1 + const postResponse = await supertestWithoutAuth + .post(`${getUrlPrefix('space1')}/internal/alerting/rules/settings/_flapping`) + .set('kbn-xsrf', 'foo') + .auth(Superuser.username, Superuser.password) + .send({ + enabled: false, + lookBackWindow: 20, + statusChangeThreshold: 20, + }); + + expect(postResponse.statusCode).to.eql(200); + expect(postResponse.body.enabled).to.eql(false); + expect(postResponse.body.lookBackWindow).to.eql(20); + expect(postResponse.body.statusChangeThreshold).to.eql(20); + + // Get the rules settings in space2 + const getResponse = await supertestWithoutAuth + .get(`${getUrlPrefix('space2')}/internal/alerting/rules/settings/_flapping`) + .auth(Superuser.username, Superuser.password); + + expect(getResponse.statusCode).to.eql(200); + expect(getResponse.body.enabled).to.eql(true); + expect(getResponse.body.lookBackWindow).to.eql(20); + expect(getResponse.body.statusChangeThreshold).to.eql(4); + }); + }); + }); +} diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts b/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts index bfa4968e2e4b5..9e0bc69a4175b 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts @@ -5,6 +5,10 @@ * 2.0. */ +import { + READ_FLAPPING_SETTINGS_SUB_FEATURE_ID, + ALL_FLAPPING_SETTINGS_SUB_FEATURE_ID, +} from '@kbn/alerting-plugin/common'; import { ES_TEST_INDEX_NAME } from '@kbn/alerting-api-integration-helpers'; import { Space, User } from '../common/types'; @@ -51,6 +55,7 @@ const GlobalRead: User = { alertsFixture: ['read'], alertsRestrictedFixture: ['read'], actionsSimulators: ['read'], + rulesSettings: ['read', READ_FLAPPING_SETTINGS_SUB_FEATURE_ID], }, spaces: ['*'], }, @@ -78,6 +83,7 @@ const Space1All: User = { actions: ['all'], alertsFixture: ['all'], actionsSimulators: ['all'], + rulesSettings: ['all', ALL_FLAPPING_SETTINGS_SUB_FEATURE_ID], }, spaces: ['space1'], }, diff --git a/x-pack/test/api_integration/apis/features/features/features.ts b/x-pack/test/api_integration/apis/features/features/features.ts index ce937a5e4618e..57012451eeb45 100644 --- a/x-pack/test/api_integration/apis/features/features/features.ts +++ b/x-pack/test/api_integration/apis/features/features/features.ts @@ -118,6 +118,7 @@ export default function ({ getService }: FtrProviderContext) { 'logs', 'maps', 'osquery', + 'rulesSettings', 'uptime', 'siem', 'securitySolutionCases', diff --git a/x-pack/test/api_integration/apis/security/privileges.ts b/x-pack/test/api_integration/apis/security/privileges.ts index 5e2c0dcc25742..ba81febadfece 100644 --- a/x-pack/test/api_integration/apis/security/privileges.ts +++ b/x-pack/test/api_integration/apis/security/privileges.ts @@ -92,6 +92,14 @@ export default function ({ getService }: FtrProviderContext) { ], filesManagement: ['all', 'read', 'minimal_all', 'minimal_read'], filesSharedImage: ['all', 'read', 'minimal_all', 'minimal_read'], + rulesSettings: [ + 'all', + 'read', + 'minimal_all', + 'minimal_read', + 'allFlappingSettings', + 'readFlappingSettings', + ], }, reserved: ['fleet-setup', 'ml_user', 'ml_admin', 'ml_apm_user', 'monitoring'], }; diff --git a/x-pack/test/api_integration/apis/security/privileges_basic.ts b/x-pack/test/api_integration/apis/security/privileges_basic.ts index 63f0b922a30e0..36cb665c838f4 100644 --- a/x-pack/test/api_integration/apis/security/privileges_basic.ts +++ b/x-pack/test/api_integration/apis/security/privileges_basic.ts @@ -47,6 +47,7 @@ export default function ({ getService }: FtrProviderContext) { actions: ['all', 'read', 'minimal_all', 'minimal_read'], filesManagement: ['all', 'read', 'minimal_all', 'minimal_read'], filesSharedImage: ['all', 'read', 'minimal_all', 'minimal_read'], + rulesSettings: ['all', 'read', 'minimal_all', 'minimal_read'], }, global: ['all', 'read'], space: ['all', 'read'], @@ -161,6 +162,14 @@ export default function ({ getService }: FtrProviderContext) { 'packs_all', 'packs_read', ], + rulesSettings: [ + 'all', + 'read', + 'minimal_all', + 'minimal_read', + 'allFlappingSettings', + 'readFlappingSettings', + ], }, reserved: ['fleet-setup', 'ml_user', 'ml_admin', 'ml_apm_user', 'monitoring'], }; diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/index.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/index.ts index 00f008519f237..bf9f30f34bb3f 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/index.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/index.ts @@ -15,5 +15,6 @@ export default ({ loadTestFile, getService }: FtrProviderContext) => { loadTestFile(require.resolve('./details')); loadTestFile(require.resolve('./connectors')); loadTestFile(require.resolve('./logs_list')); + loadTestFile(require.resolve('./rules_settings')); }); }; diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rules_settings.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rules_settings.ts new file mode 100644 index 0000000000000..6b4297f2dc153 --- /dev/null +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rules_settings.ts @@ -0,0 +1,139 @@ +/* + * 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 expect from '@kbn/expect'; +import { createAlert } from '../../lib/alert_api_actions'; +import { ObjectRemover } from '../../lib/object_remover'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default ({ getPageObjects, getService }: FtrProviderContext) => { + const testSubjects = getService('testSubjects'); + const supertest = getService('supertest'); + const pageObjects = getPageObjects(['common', 'triggersActionsUI', 'header', 'security']); + const browser = getService('browser'); + const objectRemover = new ObjectRemover(supertest); + const retry = getService('retry'); + + async function refreshAlertsList() { + await retry.try(async () => { + await pageObjects.common.navigateToApp('triggersActions'); + await testSubjects.click('triggersActions'); + const searchResults = await pageObjects.triggersActionsUI.getAlertsList(); + expect(searchResults).to.have.length(1); + }); + } + + async function dragRangeInput( + testId: string, + steps: number = 1, + direction: 'left' | 'right' = 'right' + ) { + const inputEl = await testSubjects.find(testId); + await inputEl.focus(); + const browserKey = direction === 'left' ? browser.keys.LEFT : browser.keys.RIGHT; + while (steps--) { + await browser.pressKeys(browserKey); + } + } + + describe('rules settings modal', () => { + before(async () => { + await supertest + .post(`/internal/alerting/rules/settings/_flapping`) + .set('kbn-xsrf', 'foo') + .send({ + enabled: true, + lookBackWindow: 10, + statusChangeThreshold: 10, + }) + .expect(200); + }); + + beforeEach(async () => { + await createAlert({ + supertest, + objectRemover, + }); + await refreshAlertsList(); + }); + + afterEach(async () => { + await objectRemover.removeAll(); + }); + + it('rules settings link should be enabled', async () => { + await testSubjects.existOrFail('rulesSettingsLink'); + const button = await testSubjects.find('rulesSettingsLink'); + const isDisabled = await button.getAttribute('disabled'); + expect(isDisabled).to.equal(null); + }); + + it('should allow the user to open up the rules settings modal', async () => { + await testSubjects.click('rulesSettingsLink'); + await testSubjects.existOrFail('rulesSettingsModal'); + await testSubjects.waitForDeleted('centerJustifiedSpinner'); + + // Flapping enabled by default + await testSubjects.missingOrFail('rulesSettingsModalFlappingOffPrompt'); + + await testSubjects.existOrFail('rulesSettingsModalEnableSwitch'); + await testSubjects.existOrFail('lookBackWindowRangeInput'); + await testSubjects.existOrFail('statusChangeThresholdRangeInput'); + + const lookBackWindowInput = await testSubjects.find('lookBackWindowRangeInput'); + const statusChangeThresholdInput = await testSubjects.find('statusChangeThresholdRangeInput'); + + const lookBackWindowValue = await lookBackWindowInput.getAttribute('value'); + const statusChangeThresholdValue = await statusChangeThresholdInput.getAttribute('value'); + + expect(lookBackWindowValue).to.eql('10'); + expect(statusChangeThresholdValue).to.eql('10'); + }); + + it('should allow the user to modify rules settings', async () => { + await testSubjects.click('rulesSettingsLink'); + await testSubjects.waitForDeleted('centerJustifiedSpinner'); + + await dragRangeInput('lookBackWindowRangeInput', 5, 'right'); + await dragRangeInput('statusChangeThresholdRangeInput', 5, 'left'); + + let lookBackWindowInput = await testSubjects.find('lookBackWindowRangeInput'); + let statusChangeThresholdInput = await testSubjects.find('statusChangeThresholdRangeInput'); + + let lookBackWindowValue = await lookBackWindowInput.getAttribute('value'); + let statusChangeThresholdValue = await statusChangeThresholdInput.getAttribute('value'); + + expect(lookBackWindowValue).to.eql('15'); + expect(statusChangeThresholdValue).to.eql('5'); + + await testSubjects.click('rulesSettingsModalEnableSwitch'); + await testSubjects.existOrFail('rulesSettingsModalFlappingOffPrompt'); + + // Save + await testSubjects.click('rulesSettingsModalSaveButton'); + await pageObjects.header.waitUntilLoadingHasFinished(); + await testSubjects.missingOrFail('rulesSettingsModal'); + + // Open up the modal again + await testSubjects.click('rulesSettingsLink'); + await testSubjects.waitForDeleted('centerJustifiedSpinner'); + + // Flapping initially disabled + await testSubjects.existOrFail('rulesSettingsModalFlappingOffPrompt'); + await testSubjects.click('rulesSettingsModalEnableSwitch'); + + lookBackWindowInput = await testSubjects.find('lookBackWindowRangeInput'); + statusChangeThresholdInput = await testSubjects.find('statusChangeThresholdRangeInput'); + + lookBackWindowValue = await lookBackWindowInput.getAttribute('value'); + statusChangeThresholdValue = await statusChangeThresholdInput.getAttribute('value'); + + expect(lookBackWindowValue).to.eql('15'); + expect(statusChangeThresholdValue).to.eql('5'); + }); + }); +}; From de865e90bad9cfce348a0fe221be21102df2081f Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 18 Jan 2023 00:52:36 -0500 Subject: [PATCH 22/44] [api-docs] 2023-01-18 Daily api_docs build (#149089) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/221 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.devdocs.json | 447 ++++++++++++++++++ api_docs/alerting.mdx | 4 +- api_docs/apm.devdocs.json | 138 +++++- api_docs/apm.mdx | 4 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_chat.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/core.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 2 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.mdx | 2 +- api_docs/features.devdocs.json | 149 +++++- api_docs/features.mdx | 4 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- api_docs/kbn_alerts.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_analytics_shippers_gainsight.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_cases_components.devdocs.json | 233 ++++++++- api_docs/kbn_cases_components.mdx | 7 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_content_editor.mdx | 2 +- .../kbn_content_management_table_list.mdx | 2 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_apps_server_internal.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.mdx | 2 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_custom_branding_browser.mdx | 2 +- ..._core_custom_branding_browser_internal.mdx | 2 +- ...kbn_core_custom_branding_browser_mocks.mdx | 2 +- api_docs/kbn_core_custom_branding_common.mdx | 2 +- api_docs/kbn_core_custom_branding_server.mdx | 2 +- ...n_core_custom_branding_server_internal.mdx | 2 +- .../kbn_core_custom_branding_server_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- ...kbn_core_deprecations_browser_internal.mdx | 2 +- .../kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- .../kbn_core_deprecations_server_internal.mdx | 2 +- .../kbn_core_deprecations_server_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_browser.mdx | 2 +- api_docs/kbn_core_doc_links_browser_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_server.mdx | 2 +- api_docs/kbn_core_doc_links_server_mocks.mdx | 2 +- ...e_elasticsearch_client_server_internal.mdx | 2 +- ...core_elasticsearch_client_server_mocks.mdx | 2 +- api_docs/kbn_core_elasticsearch_server.mdx | 2 +- ...kbn_core_elasticsearch_server_internal.mdx | 2 +- .../kbn_core_elasticsearch_server_mocks.mdx | 2 +- .../kbn_core_environment_server_internal.mdx | 2 +- .../kbn_core_environment_server_mocks.mdx | 2 +- .../kbn_core_execution_context_browser.mdx | 2 +- ...ore_execution_context_browser_internal.mdx | 2 +- ...n_core_execution_context_browser_mocks.mdx | 2 +- .../kbn_core_execution_context_common.mdx | 2 +- .../kbn_core_execution_context_server.mdx | 2 +- ...core_execution_context_server_internal.mdx | 2 +- ...bn_core_execution_context_server_mocks.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser.mdx | 2 +- .../kbn_core_fatal_errors_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_browser.mdx | 2 +- api_docs/kbn_core_http_browser_internal.mdx | 2 +- api_docs/kbn_core_http_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_common.mdx | 2 +- .../kbn_core_http_context_server_mocks.mdx | 2 +- ...re_http_request_handler_context_server.mdx | 2 +- api_docs/kbn_core_http_resources_server.mdx | 2 +- ...bn_core_http_resources_server_internal.mdx | 2 +- .../kbn_core_http_resources_server_mocks.mdx | 2 +- .../kbn_core_http_router_server_internal.mdx | 2 +- .../kbn_core_http_router_server_mocks.mdx | 2 +- api_docs/kbn_core_http_server.mdx | 2 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- .../kbn_core_http_server_mocks.devdocs.json | 4 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_browser.mdx | 2 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_server.mdx | 2 +- api_docs/kbn_core_lifecycle_server_mocks.mdx | 2 +- api_docs/kbn_core_logging_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_common_internal.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_server.mdx | 2 +- api_docs/kbn_core_plugins_server_mocks.mdx | 2 +- api_docs/kbn_core_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- .../kbn_core_rendering_server_internal.mdx | 2 +- api_docs/kbn_core_rendering_server_mocks.mdx | 2 +- api_docs/kbn_core_root_server_internal.mdx | 2 +- .../kbn_core_saved_objects_api_browser.mdx | 2 +- .../kbn_core_saved_objects_api_server.mdx | 2 +- ...core_saved_objects_api_server_internal.mdx | 2 +- ...bn_core_saved_objects_api_server_mocks.mdx | 2 +- ...ore_saved_objects_base_server_internal.mdx | 2 +- ...n_core_saved_objects_base_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_browser.mdx | 2 +- ...bn_core_saved_objects_browser_internal.mdx | 2 +- .../kbn_core_saved_objects_browser_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_common.mdx | 2 +- ..._objects_import_export_server_internal.mdx | 2 +- ...ved_objects_import_export_server_mocks.mdx | 2 +- ...aved_objects_migration_server_internal.mdx | 2 +- ...e_saved_objects_migration_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_server.mdx | 2 +- ...kbn_core_saved_objects_server_internal.mdx | 2 +- .../kbn_core_saved_objects_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_utils_server.mdx | 2 +- api_docs/kbn_core_status_common.mdx | 2 +- api_docs/kbn_core_status_common_internal.mdx | 2 +- api_docs/kbn_core_status_server.mdx | 2 +- api_docs/kbn_core_status_server_internal.mdx | 2 +- api_docs/kbn_core_status_server_mocks.mdx | 2 +- ...core_test_helpers_deprecations_getters.mdx | 2 +- ...n_core_test_helpers_http_setup_browser.mdx | 2 +- api_docs/kbn_core_test_helpers_kbn_server.mdx | 2 +- ...n_core_test_helpers_so_type_serializer.mdx | 2 +- api_docs/kbn_core_test_helpers_test_utils.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_internal.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_cypress_config.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_ecs.mdx | 2 +- api_docs/kbn_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_get_repo_files.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.devdocs.json | 4 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_date_picker.mdx | 2 +- api_docs/kbn_ml_is_defined.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_local_storage.mdx | 2 +- api_docs/kbn_ml_nested_property.mdx | 2 +- api_docs/kbn_ml_query_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_repo_file_maps.mdx | 2 +- api_docs/kbn_repo_linter.mdx | 2 +- api_docs/kbn_repo_path.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- ...securitysolution_autocomplete.devdocs.json | 4 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ion_exception_list_components.devdocs.json | 10 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- ...ritysolution_io_ts_list_types.devdocs.json | 106 ++--- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- ...kbn_securitysolution_list_api.devdocs.json | 20 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- ...n_securitysolution_list_hooks.devdocs.json | 44 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- ...n_securitysolution_list_utils.devdocs.json | 22 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- api_docs/kbn_shared_ux_avatar_solution.mdx | 2 +- ...ared_ux_avatar_user_profile_components.mdx | 2 +- .../kbn_shared_ux_button_exit_full_screen.mdx | 2 +- ...hared_ux_button_exit_full_screen_mocks.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_context.mdx | 2 +- api_docs/kbn_shared_ux_file_image.mdx | 2 +- api_docs/kbn_shared_ux_file_image_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_picker.mdx | 2 +- api_docs/kbn_shared_ux_file_upload.mdx | 2 +- api_docs/kbn_shared_ux_file_util.mdx | 2 +- api_docs/kbn_shared_ux_link_redirect_app.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- api_docs/kbn_shared_ux_markdown.mdx | 2 +- api_docs/kbn_shared_ux_markdown_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_prompt_not_found.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_slo_schema.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_ts_projects.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_shared_deps_src.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.mdx | 2 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/lists.devdocs.json | 64 +-- api_docs/lists.mdx | 2 +- api_docs/management.mdx | 2 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/ml.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/notifications.mdx | 2 +- api_docs/observability.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/plugin_directory.mdx | 16 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/threat_intelligence.devdocs.json | 18 + api_docs/threat_intelligence.mdx | 4 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.mdx | 2 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_field_list.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 482 files changed, 1599 insertions(+), 627 deletions(-) diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 2677696e92dda..a1b7ce979d156 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index 50159ff14180f..31945daf7dfb1 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 56d8231da0f7d..c90bf9ae33168 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.devdocs.json b/api_docs/alerting.devdocs.json index 83f0ad7016c38..7bdaef809e7b6 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -1054,6 +1054,23 @@ "children": [], "returnComment": [] }, + { + "parentPluginId": "alerting", + "id": "def-server.AlertingApiRequestHandlerContext.getRulesSettingsClient", + "type": "Function", + "tags": [], + "label": "getRulesSettingsClient", + "description": [], + "signature": [ + "() => ", + "RulesSettingsClient" + ], + "path": "x-pack/plugins/alerting/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "alerting", "id": "def-server.AlertingApiRequestHandlerContext.listTypes", @@ -6549,6 +6566,159 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettings", + "type": "Interface", + "tags": [], + "label": "RulesSettings", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettings.flapping", + "type": "CompoundType", + "tags": [], + "label": "flapping", + "description": [], + "signature": [ + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RulesSettingsFlappingProperties", + "text": "RulesSettingsFlappingProperties" + }, + " & ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RulesSettingsModificationMetadata", + "text": "RulesSettingsModificationMetadata" + } + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsFlappingProperties", + "type": "Interface", + "tags": [], + "label": "RulesSettingsFlappingProperties", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsFlappingProperties.enabled", + "type": "boolean", + "tags": [], + "label": "enabled", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsFlappingProperties.lookBackWindow", + "type": "number", + "tags": [], + "label": "lookBackWindow", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsFlappingProperties.statusChangeThreshold", + "type": "number", + "tags": [], + "label": "statusChangeThreshold", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsModificationMetadata", + "type": "Interface", + "tags": [], + "label": "RulesSettingsModificationMetadata", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsModificationMetadata.createdBy", + "type": "CompoundType", + "tags": [], + "label": "createdBy", + "description": [], + "signature": [ + "string | null" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsModificationMetadata.updatedBy", + "type": "CompoundType", + "tags": [], + "label": "updatedBy", + "description": [], + "signature": [ + "string | null" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsModificationMetadata.createdAt", + "type": "string", + "tags": [], + "label": "createdAt", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsModificationMetadata.updatedAt", + "type": "string", + "tags": [], + "label": "updatedAt", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.RuleStateNavigation", @@ -7027,6 +7197,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.ALL_FLAPPING_SETTINGS_SUB_FEATURE_ID", + "type": "string", + "tags": [], + "label": "ALL_FLAPPING_SETTINGS_SUB_FEATURE_ID", + "description": [], + "signature": [ + "\"allFlappingSettings\"" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.BASE_ALERTING_API_PATH", @@ -7057,6 +7242,36 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.DEFAULT_LOOK_BACK_WINDOW", + "type": "number", + "tags": [], + "label": "DEFAULT_LOOK_BACK_WINDOW", + "description": [], + "signature": [ + "20" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.DEFAULT_STATUS_CHANGE_THRESHOLD", + "type": "number", + "tags": [], + "label": "DEFAULT_STATUS_CHANGE_THRESHOLD", + "description": [], + "signature": [ + "4" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.DefaultActionGroupId", @@ -7176,6 +7391,66 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.MAX_LOOK_BACK_WINDOW", + "type": "number", + "tags": [], + "label": "MAX_LOOK_BACK_WINDOW", + "description": [], + "signature": [ + "20" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.MAX_STATUS_CHANGE_THRESHOLD", + "type": "number", + "tags": [], + "label": "MAX_STATUS_CHANGE_THRESHOLD", + "description": [], + "signature": [ + "20" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.MIN_LOOK_BACK_WINDOW", + "type": "number", + "tags": [], + "label": "MIN_LOOK_BACK_WINDOW", + "description": [], + "signature": [ + "2" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.MIN_STATUS_CHANGE_THRESHOLD", + "type": "number", + "tags": [], + "label": "MIN_STATUS_CHANGE_THRESHOLD", + "description": [], + "signature": [ + "2" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.MONITORING_HISTORY_LIMIT", @@ -7206,6 +7481,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.READ_FLAPPING_SETTINGS_SUB_FEATURE_ID", + "type": "string", + "tags": [], + "label": "READ_FLAPPING_SETTINGS_SUB_FEATURE_ID", + "description": [], + "signature": [ + "\"readFlappingSettings\"" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.RecoveredActionGroupId", @@ -7406,6 +7696,51 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.RULES_SETTINGS_FEATURE_ID", + "type": "string", + "tags": [], + "label": "RULES_SETTINGS_FEATURE_ID", + "description": [], + "signature": [ + "\"rulesSettings\"" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RULES_SETTINGS_SAVED_OBJECT_ID", + "type": "string", + "tags": [], + "label": "RULES_SETTINGS_SAVED_OBJECT_ID", + "description": [], + "signature": [ + "\"rules-settings\"" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RULES_SETTINGS_SAVED_OBJECT_TYPE", + "type": "string", + "tags": [], + "label": "RULES_SETTINGS_SAVED_OBJECT_TYPE", + "description": [], + "signature": [ + "\"rules-settings\"" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.RuleSnooze", @@ -7421,6 +7756,35 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsFlapping", + "type": "Type", + "tags": [], + "label": "RulesSettingsFlapping", + "description": [], + "signature": [ + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RulesSettingsFlappingProperties", + "text": "RulesSettingsFlappingProperties" + }, + " & ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RulesSettingsModificationMetadata", + "text": "RulesSettingsModificationMetadata" + } + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.RuleStatusValues", @@ -7630,6 +7994,89 @@ } ], "objects": [ + { + "parentPluginId": "alerting", + "id": "def-common.API_PRIVILEGES", + "type": "Object", + "tags": [], + "label": "API_PRIVILEGES", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "alerting", + "id": "def-common.API_PRIVILEGES.READ_FLAPPING_SETTINGS", + "type": "string", + "tags": [], + "label": "READ_FLAPPING_SETTINGS", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.API_PRIVILEGES.WRITE_FLAPPING_SETTINGS", + "type": "string", + "tags": [], + "label": "WRITE_FLAPPING_SETTINGS", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.DEFAULT_FLAPPING_SETTINGS", + "type": "Object", + "tags": [], + "label": "DEFAULT_FLAPPING_SETTINGS", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "alerting", + "id": "def-common.DEFAULT_FLAPPING_SETTINGS.enabled", + "type": "boolean", + "tags": [], + "label": "enabled", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.DEFAULT_FLAPPING_SETTINGS.lookBackWindow", + "type": "number", + "tags": [], + "label": "lookBackWindow", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.DEFAULT_FLAPPING_SETTINGS.statusChangeThreshold", + "type": "number", + "tags": [], + "label": "statusChangeThreshold", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.DisabledActionTypeIdsForActionGroup", diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index eed0ae255efb5..5438d2f13f34a 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Response Ops](https://github.com/orgs/elastic/teams/response-ops) for q | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 434 | 0 | 425 | 37 | +| 465 | 0 | 456 | 38 | ## Client diff --git a/api_docs/apm.devdocs.json b/api_docs/apm.devdocs.json index f54c208941119..c56b5f9550718 100644 --- a/api_docs/apm.devdocs.json +++ b/api_docs/apm.devdocs.json @@ -810,7 +810,7 @@ "label": "APIEndpoint", "description": [], "signature": [ - "\"POST /internal/apm/data_view/static\" | \"GET /internal/apm/data_view/title\" | \"GET /internal/apm/environments\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics_by_transaction_name\" | \"POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/samples\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/error/{errorId}\" | \"GET /internal/apm/services/{serviceName}/errors/distribution\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/top_erroneous_transactions\" | \"POST /internal/apm/latency/overall_distribution/transactions\" | \"GET /internal/apm/services/{serviceName}/metrics/charts\" | \"GET /internal/apm/services/{serviceName}/metrics/nodes\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/charts\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/summary\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/functions_overview\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/active_instances\" | \"GET /internal/apm/observability_overview\" | \"GET /internal/apm/observability_overview/has_data\" | \"GET /internal/apm/service-map\" | \"GET /internal/apm/service-map/service/{serviceName}\" | \"GET /internal/apm/service-map/dependency\" | \"GET /internal/apm/services\" | \"POST /internal/apm/services/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/metadata/details\" | \"GET /internal/apm/services/{serviceName}/metadata/icons\" | \"GET /internal/apm/services/{serviceName}/agent\" | \"GET /internal/apm/services/{serviceName}/transaction_types\" | \"GET /internal/apm/services/{serviceName}/node/{serviceNodeName}/metadata\" | \"GET /api/apm/services/{serviceName}/annotation/search\" | \"POST /api/apm/services/{serviceName}/annotation\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/details/{serviceNodeName}\" | \"GET /internal/apm/services/{serviceName}/throughput\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/main_statistics\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/dependencies\" | \"GET /internal/apm/services/{serviceName}/dependencies/breakdown\" | \"GET /internal/apm/services/{serviceName}/anomaly_charts\" | \"GET /internal/apm/sorted_and_filtered_services\" | \"GET /internal/apm/services/{serviceName}/alerts_count\" | \"GET /internal/apm/service-groups\" | \"GET /internal/apm/service-group\" | \"POST /internal/apm/service-group\" | \"DELETE /internal/apm/service-group\" | \"GET /internal/apm/service-group/services\" | \"GET /internal/apm/service-group/counts\" | \"GET /internal/apm/suggestions\" | \"GET /internal/apm/traces/{traceId}\" | \"GET /internal/apm/traces\" | \"GET /internal/apm/traces/{traceId}/root_transaction\" | \"GET /internal/apm/transactions/{transactionId}\" | \"GET /internal/apm/traces/find\" | \"POST /internal/apm/traces/aggregated_critical_path\" | \"GET /internal/apm/traces/{traceId}/transactions/{transactionId}\" | \"GET /internal/apm/traces/{traceId}/spans/{spanId}\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/latency\" | \"GET /internal/apm/services/{serviceName}/transactions/traces/samples\" | \"GET /internal/apm/services/{serviceName}/transaction/charts/breakdown\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/error_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate_by_transaction_name\" | \"GET /internal/apm/rule_types/transaction_error_rate/chart_preview\" | \"GET /internal/apm/rule_types/transaction_duration/chart_preview\" | \"GET /internal/apm/rule_types/error_count/chart_preview\" | \"GET /api/apm/settings/agent-configuration\" | \"GET /api/apm/settings/agent-configuration/view\" | \"DELETE /api/apm/settings/agent-configuration\" | \"PUT /api/apm/settings/agent-configuration\" | \"POST /api/apm/settings/agent-configuration/search\" | \"GET /api/apm/settings/agent-configuration/environments\" | \"GET /api/apm/settings/agent-configuration/agent_name\" | \"GET /internal/apm/settings/anomaly-detection/jobs\" | \"POST /internal/apm/settings/anomaly-detection/jobs\" | \"GET /internal/apm/settings/anomaly-detection/environments\" | \"POST /internal/apm/settings/anomaly-detection/update_to_v3\" | \"GET /internal/apm/settings/apm-index-settings\" | \"GET /internal/apm/settings/apm-indices\" | \"POST /internal/apm/settings/apm-indices/save\" | \"GET /internal/apm/settings/custom_links/transaction\" | \"GET /internal/apm/settings/custom_links\" | \"POST /internal/apm/settings/custom_links\" | \"PUT /internal/apm/settings/custom_links/{id}\" | \"DELETE /internal/apm/settings/custom_links/{id}\" | \"GET /api/apm/sourcemaps\" | \"POST /api/apm/sourcemaps\" | \"DELETE /api/apm/sourcemaps/{id}\" | \"POST /internal/apm/sourcemaps/migrate_fleet_artifacts\" | \"GET /internal/apm/fleet/has_apm_policies\" | \"GET /internal/apm/fleet/agents\" | \"POST /api/apm/fleet/apm_server_schema\" | \"GET /internal/apm/fleet/apm_server_schema/unsupported\" | \"GET /internal/apm/fleet/migration_check\" | \"POST /internal/apm/fleet/cloud_apm_package_policy\" | \"GET /internal/apm/fleet/java_agent_versions\" | \"GET /internal/apm/dependencies/top_dependencies\" | \"GET /internal/apm/dependencies/upstream_services\" | \"GET /internal/apm/dependencies/metadata\" | \"GET /internal/apm/dependencies/charts/latency\" | \"GET /internal/apm/dependencies/charts/throughput\" | \"GET /internal/apm/dependencies/charts/error_rate\" | \"GET /internal/apm/dependencies/operations\" | \"GET /internal/apm/dependencies/charts/distribution\" | \"GET /internal/apm/dependencies/operations/spans\" | \"GET /internal/apm/correlations/field_candidates/transactions\" | \"GET /internal/apm/correlations/field_value_stats/transactions\" | \"POST /internal/apm/correlations/field_value_pairs/transactions\" | \"POST /internal/apm/correlations/significant_correlations/transactions\" | \"POST /internal/apm/correlations/p_values/transactions\" | \"GET /internal/apm/fallback_to_transactions\" | \"GET /internal/apm/has_data\" | \"GET /internal/apm/event_metadata/{processorEvent}/{id}\" | \"GET /internal/apm/agent_keys\" | \"GET /internal/apm/agent_keys/privileges\" | \"POST /internal/apm/api_key/invalidate\" | \"POST /api/apm/agent_keys\" | \"GET /internal/apm/storage_explorer\" | \"GET /internal/apm/services/{serviceName}/storage_details\" | \"GET /internal/apm/storage_chart\" | \"GET /internal/apm/storage_explorer/privileges\" | \"GET /internal/apm/storage_explorer_summary_stats\" | \"GET /internal/apm/storage_explorer/is_cross_cluster_search\" | \"GET /internal/apm/storage_explorer/get_services\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/parents\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/children\" | \"GET /internal/apm/services/{serviceName}/infrastructure_attributes\" | \"GET /internal/apm/debug-telemetry\" | \"GET /internal/apm/time_range_metadata\" | \"GET /internal/apm/settings/labs\" | \"GET /internal/apm/get_agents_per_service\" | \"GET /internal/apm/services/{serviceName}/agent_instances\" | \"GET /internal/apm/services/{serviceName}/mobile/filters\" | \"GET /internal/apm/mobile-services/{serviceName}/stats\"" + "\"POST /internal/apm/data_view/static\" | \"GET /internal/apm/data_view/title\" | \"GET /internal/apm/environments\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics_by_transaction_name\" | \"POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/samples\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/error/{errorId}\" | \"GET /internal/apm/services/{serviceName}/errors/distribution\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/top_erroneous_transactions\" | \"POST /internal/apm/latency/overall_distribution/transactions\" | \"GET /internal/apm/services/{serviceName}/metrics/charts\" | \"GET /internal/apm/services/{serviceName}/metrics/nodes\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/charts\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/summary\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/functions_overview\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/active_instances\" | \"GET /internal/apm/observability_overview\" | \"GET /internal/apm/observability_overview/has_data\" | \"GET /internal/apm/service-map\" | \"GET /internal/apm/service-map/service/{serviceName}\" | \"GET /internal/apm/service-map/dependency\" | \"GET /internal/apm/services\" | \"POST /internal/apm/services/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/metadata/details\" | \"GET /internal/apm/services/{serviceName}/metadata/icons\" | \"GET /internal/apm/services/{serviceName}/agent\" | \"GET /internal/apm/services/{serviceName}/transaction_types\" | \"GET /internal/apm/services/{serviceName}/node/{serviceNodeName}/metadata\" | \"GET /api/apm/services/{serviceName}/annotation/search\" | \"POST /api/apm/services/{serviceName}/annotation\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/details/{serviceNodeName}\" | \"GET /internal/apm/services/{serviceName}/throughput\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/main_statistics\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/dependencies\" | \"GET /internal/apm/services/{serviceName}/dependencies/breakdown\" | \"GET /internal/apm/services/{serviceName}/anomaly_charts\" | \"GET /internal/apm/sorted_and_filtered_services\" | \"GET /internal/apm/services/{serviceName}/alerts_count\" | \"GET /internal/apm/service-groups\" | \"GET /internal/apm/service-group\" | \"POST /internal/apm/service-group\" | \"DELETE /internal/apm/service-group\" | \"GET /internal/apm/service-group/services\" | \"GET /internal/apm/service-group/counts\" | \"GET /internal/apm/suggestions\" | \"GET /internal/apm/traces/{traceId}\" | \"GET /internal/apm/traces\" | \"GET /internal/apm/traces/{traceId}/root_transaction\" | \"GET /internal/apm/transactions/{transactionId}\" | \"GET /internal/apm/traces/find\" | \"POST /internal/apm/traces/aggregated_critical_path\" | \"GET /internal/apm/traces/{traceId}/transactions/{transactionId}\" | \"GET /internal/apm/traces/{traceId}/spans/{spanId}\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/latency\" | \"GET /internal/apm/services/{serviceName}/transactions/traces/samples\" | \"GET /internal/apm/services/{serviceName}/transaction/charts/breakdown\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/error_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate_by_transaction_name\" | \"GET /internal/apm/rule_types/transaction_error_rate/chart_preview\" | \"GET /internal/apm/rule_types/transaction_duration/chart_preview\" | \"GET /internal/apm/rule_types/error_count/chart_preview\" | \"GET /api/apm/settings/agent-configuration\" | \"GET /api/apm/settings/agent-configuration/view\" | \"DELETE /api/apm/settings/agent-configuration\" | \"PUT /api/apm/settings/agent-configuration\" | \"POST /api/apm/settings/agent-configuration/search\" | \"GET /api/apm/settings/agent-configuration/environments\" | \"GET /api/apm/settings/agent-configuration/agent_name\" | \"GET /internal/apm/settings/anomaly-detection/jobs\" | \"POST /internal/apm/settings/anomaly-detection/jobs\" | \"GET /internal/apm/settings/anomaly-detection/environments\" | \"POST /internal/apm/settings/anomaly-detection/update_to_v3\" | \"GET /internal/apm/settings/apm-index-settings\" | \"GET /internal/apm/settings/apm-indices\" | \"POST /internal/apm/settings/apm-indices/save\" | \"GET /internal/apm/settings/custom_links/transaction\" | \"GET /internal/apm/settings/custom_links\" | \"POST /internal/apm/settings/custom_links\" | \"PUT /internal/apm/settings/custom_links/{id}\" | \"DELETE /internal/apm/settings/custom_links/{id}\" | \"GET /api/apm/sourcemaps\" | \"POST /api/apm/sourcemaps\" | \"DELETE /api/apm/sourcemaps/{id}\" | \"POST /internal/apm/sourcemaps/migrate_fleet_artifacts\" | \"GET /internal/apm/fleet/has_apm_policies\" | \"GET /internal/apm/fleet/agents\" | \"POST /api/apm/fleet/apm_server_schema\" | \"GET /internal/apm/fleet/apm_server_schema/unsupported\" | \"GET /internal/apm/fleet/migration_check\" | \"POST /internal/apm/fleet/cloud_apm_package_policy\" | \"GET /internal/apm/fleet/java_agent_versions\" | \"GET /internal/apm/dependencies/top_dependencies\" | \"GET /internal/apm/dependencies/upstream_services\" | \"GET /internal/apm/dependencies/metadata\" | \"GET /internal/apm/dependencies/charts/latency\" | \"GET /internal/apm/dependencies/charts/throughput\" | \"GET /internal/apm/dependencies/charts/error_rate\" | \"GET /internal/apm/dependencies/operations\" | \"GET /internal/apm/dependencies/charts/distribution\" | \"GET /internal/apm/dependencies/operations/spans\" | \"GET /internal/apm/correlations/field_candidates/transactions\" | \"GET /internal/apm/correlations/field_value_stats/transactions\" | \"POST /internal/apm/correlations/field_value_pairs/transactions\" | \"POST /internal/apm/correlations/significant_correlations/transactions\" | \"POST /internal/apm/correlations/p_values/transactions\" | \"GET /internal/apm/fallback_to_transactions\" | \"GET /internal/apm/has_data\" | \"GET /internal/apm/event_metadata/{processorEvent}/{id}\" | \"GET /internal/apm/agent_keys\" | \"GET /internal/apm/agent_keys/privileges\" | \"POST /internal/apm/api_key/invalidate\" | \"POST /api/apm/agent_keys\" | \"GET /internal/apm/storage_explorer\" | \"GET /internal/apm/services/{serviceName}/storage_details\" | \"GET /internal/apm/storage_chart\" | \"GET /internal/apm/storage_explorer/privileges\" | \"GET /internal/apm/storage_explorer_summary_stats\" | \"GET /internal/apm/storage_explorer/is_cross_cluster_search\" | \"GET /internal/apm/storage_explorer/get_services\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/parents\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/children\" | \"GET /internal/apm/services/{serviceName}/infrastructure_attributes\" | \"GET /internal/apm/debug-telemetry\" | \"GET /internal/apm/time_range_metadata\" | \"GET /internal/apm/settings/labs\" | \"GET /internal/apm/get_agents_per_service\" | \"GET /internal/apm/services/{serviceName}/agent_instances\" | \"GET /internal/apm/services/{serviceName}/mobile/filters\" | \"GET /internal/apm/mobile-services/{serviceName}/transactions/charts/sessions\" | \"GET /internal/apm/mobile-services/{serviceName}/transactions/charts/http_requests\" | \"GET /internal/apm/mobile-services/{serviceName}/stats\"" ], "path": "x-pack/plugins/apm/server/routes/apm_routes/get_global_apm_server_route_repository.ts", "deprecated": false, @@ -934,6 +934,142 @@ "MobileStats", ", ", "APMRouteCreateOptions", + ">; \"GET /internal/apm/mobile-services/{serviceName}/transactions/charts/http_requests\": ", + { + "pluginId": "@kbn/server-route-repository", + "scope": "public", + "docId": "kibKbnServerRouteRepositoryPluginApi", + "section": "def-public.ServerRoute", + "text": "ServerRoute" + }, + "<\"GET /internal/apm/mobile-services/{serviceName}/transactions/charts/http_requests\", ", + "TypeC", + "<{ path: ", + "TypeC", + "<{ serviceName: ", + "StringC", + "; }>; query: ", + "IntersectionC", + "<[", + "TypeC", + "<{ kuery: ", + "StringC", + "; }>, ", + "TypeC", + "<{ start: ", + "Type", + "; end: ", + "Type", + "; }>, ", + "TypeC", + "<{ environment: ", + "UnionC", + "<[", + "LiteralC", + "<\"ENVIRONMENT_NOT_DEFINED\">, ", + "LiteralC", + "<\"ENVIRONMENT_ALL\">, ", + "BrandC", + "<", + "StringC", + ", ", + { + "pluginId": "@kbn/io-ts-utils", + "scope": "common", + "docId": "kibKbnIoTsUtilsPluginApi", + "section": "def-common.NonEmptyStringBrand", + "text": "NonEmptyStringBrand" + }, + ">]>; }>, ", + "PartialC", + "<{ offset: ", + "StringC", + "; }>, ", + "PartialC", + "<{ transactionType: ", + "StringC", + "; transactionName: ", + "StringC", + "; }>]>; }>, ", + { + "pluginId": "apm", + "scope": "server", + "docId": "kibApmPluginApi", + "section": "def-server.APMRouteHandlerResources", + "text": "APMRouteHandlerResources" + }, + ", ", + "HttpRequestsTimeseries", + ", ", + "APMRouteCreateOptions", + ">; \"GET /internal/apm/mobile-services/{serviceName}/transactions/charts/sessions\": ", + { + "pluginId": "@kbn/server-route-repository", + "scope": "public", + "docId": "kibKbnServerRouteRepositoryPluginApi", + "section": "def-public.ServerRoute", + "text": "ServerRoute" + }, + "<\"GET /internal/apm/mobile-services/{serviceName}/transactions/charts/sessions\", ", + "TypeC", + "<{ path: ", + "TypeC", + "<{ serviceName: ", + "StringC", + "; }>; query: ", + "IntersectionC", + "<[", + "TypeC", + "<{ kuery: ", + "StringC", + "; }>, ", + "TypeC", + "<{ start: ", + "Type", + "; end: ", + "Type", + "; }>, ", + "TypeC", + "<{ environment: ", + "UnionC", + "<[", + "LiteralC", + "<\"ENVIRONMENT_NOT_DEFINED\">, ", + "LiteralC", + "<\"ENVIRONMENT_ALL\">, ", + "BrandC", + "<", + "StringC", + ", ", + { + "pluginId": "@kbn/io-ts-utils", + "scope": "common", + "docId": "kibKbnIoTsUtilsPluginApi", + "section": "def-common.NonEmptyStringBrand", + "text": "NonEmptyStringBrand" + }, + ">]>; }>, ", + "PartialC", + "<{ offset: ", + "StringC", + "; }>, ", + "PartialC", + "<{ transactionType: ", + "StringC", + "; transactionName: ", + "StringC", + "; }>]>; }>, ", + { + "pluginId": "apm", + "scope": "server", + "docId": "kibApmPluginApi", + "section": "def-server.APMRouteHandlerResources", + "text": "APMRouteHandlerResources" + }, + ", ", + "SessionsTimeseries", + ", ", + "APMRouteCreateOptions", ">; \"GET /internal/apm/services/{serviceName}/mobile/filters\": ", { "pluginId": "@kbn/server-route-repository", diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 87f38f27fd781..1e00334016007 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; @@ -21,7 +21,7 @@ Contact [APM UI](https://github.com/orgs/elastic/teams/apm-ui) for questions reg | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 42 | 0 | 42 | 59 | +| 42 | 0 | 42 | 61 | ## Client diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 464a3b0d7367c..79031fcac7ebf 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] --- import bannersObj from './banners.devdocs.json'; diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index f928b4c55e53c..2091075c1a9ae 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] --- import bfetchObj from './bfetch.devdocs.json'; diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index f39b11a17a9b2..7d38c8891f767 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index 37f341a14498b..7221d2fe903f8 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index 66550bb191560..c8a1bb56065a3 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 5af70ae503009..5cb39015197c6 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx index 11336b0e580c0..90d9d098c4769 100644 --- a/api_docs/cloud_chat.mdx +++ b/api_docs/cloud_chat.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChat title: "cloudChat" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChat plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index 7eea141fa303a..06851fa4d4f26 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDataMigration'] --- import cloudDataMigrationObj from './cloud_data_migration.devdocs.json'; diff --git a/api_docs/cloud_defend.mdx b/api_docs/cloud_defend.mdx index c07c78ab4fbc2..3caf7e892c17d 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index b2c4c9edf8004..b4d5c9985577c 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 4ff618c45d13d..7ea6accf144ce 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index fb78d9edaba21..5b9341c0bb1c2 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index ec9f3de94abd3..e743d05c9e508 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/core.mdx b/api_docs/core.mdx index 5b64aeff6fcab..131673b3ea265 100644 --- a/api_docs/core.mdx +++ b/api_docs/core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/core title: "core" image: https://source.unsplash.com/400x175/?github description: API docs for the core plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core'] --- import coreObj from './core.devdocs.json'; diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index 16e37fed21104..786f7d999daf9 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index 33a2fec555cb7..8be7ee29035cd 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index 384acd1e3982a..ba8a99d190ea1 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 815e92c6fc568..9e5eafd973542 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 028acb4a3d06f..dcff8c8f1d7b1 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 36455cb532773..f0b87249c1ad9 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index a6585ae459b14..a98687effa085 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index 471fc82c5e40b..4f37bb3608f12 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index ae15fb204da2d..bd2904fd625eb 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index 5d4bfd3d69ca6..c7fbb77db91f8 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index 2a936aa067455..ca0c5c86d0308 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 531ed7fa267f4..3d376728a8342 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index ab2e6dcb1361d..f07c2381e15d5 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 13faee411b91f..f41198da286db 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 78fbabd944012..eff8274043ded 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 449d661252295..2d2525811bda0 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index b9ba158e2316f..b95768b92fdc6 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 0defb4454798f..f1b5afab243dd 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index da843f308dbeb..86a19aadcd2a8 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index a6ecfb3b327cb..22e8a25f5ad62 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index 43b3e968785c3..5440713ff4e8f 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 00a8841d35fed..ba44b3bb65477 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 88e63ec039ff0..686921c335db9 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 714baafa70ff4..2fefd1cdecd24 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index cbb90dd70b912..f538215cd00c9 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index d3321177602b5..0375b2ae8c575 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index f0e90b0a91a88..0ef4c6e241702 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index d649fc69d8d74..b6d8573862df6 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index 36a6fa9028942..cc9b04694c13c 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index 57b53021b8f92..02022f798586a 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index 78a0cd4da57ef..67329af2adccd 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index 7dae36fe02731..464165ef1ca15 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index 5aca2b77ea366..59974d4686901 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index 96688d4613595..d9bad00c4d5d4 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index 2fd243d1f02bf..9a2d2dcc0123d 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index 22fc486a051e6..fea88ab3ecb58 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index caa976326e39d..eef598ed81c11 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index dc2d6ef248055..ee158c5a8f563 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; diff --git a/api_docs/features.devdocs.json b/api_docs/features.devdocs.json index 6831369f3b147..01692bc13b431 100644 --- a/api_docs/features.devdocs.json +++ b/api_docs/features.devdocs.json @@ -56,7 +56,7 @@ "label": "config", "description": [], "signature": [ - "Readonly<{ id: string; name: string; category: Readonly<{ id: string; label: string; ariaLabel?: string | undefined; order?: number | undefined; euiIconType?: string | undefined; }>; order?: number | undefined; excludeFromBasePrivileges?: boolean | undefined; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; app: readonly string[]; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: readonly string[] | undefined; cases?: readonly string[] | undefined; privileges: Readonly<{ all: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; read: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }> | null; subFeatures?: readonly Readonly<{ name: string; requireAllSpaces?: boolean | undefined; privilegesTooltip?: string | undefined; privilegeGroups: readonly Readonly<{ groupType: ", + "Readonly<{ id: string; name: string; description?: string | undefined; category: Readonly<{ id: string; label: string; ariaLabel?: string | undefined; order?: number | undefined; euiIconType?: string | undefined; }>; order?: number | undefined; excludeFromBasePrivileges?: boolean | undefined; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; app: readonly string[]; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: readonly string[] | undefined; cases?: readonly string[] | undefined; privileges: Readonly<{ all: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; read: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }> | null; subFeatures?: readonly Readonly<{ name: string; requireAllSpaces?: boolean | undefined; privilegesTooltip?: string | undefined; privilegeGroups: readonly Readonly<{ groupType: ", { "pluginId": "features", "scope": "common", @@ -64,7 +64,7 @@ "section": "def-common.SubFeaturePrivilegeGroupType", "text": "SubFeaturePrivilegeGroupType" }, - "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; }>[] | undefined; privilegesTooltip?: string | undefined; reserved?: Readonly<{ description: string; privileges: readonly Readonly<{ id: string; privilege: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }>[]; }> | undefined; }>" + "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; description?: string | undefined; }>[] | undefined; privilegesTooltip?: string | undefined; reserved?: Readonly<{ description: string; privileges: readonly Readonly<{ id: string; privilege: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }>[]; }> | undefined; }>" ], "path": "x-pack/plugins/features/common/kibana_feature.ts", "deprecated": false, @@ -96,6 +96,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "features", + "id": "def-public.KibanaFeature.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/kibana_feature.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "features", "id": "def-public.KibanaFeature.order", @@ -556,6 +570,22 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "features", + "id": "def-public.KibanaFeatureConfig.description", + "type": "string", + "tags": [], + "label": "description", + "description": [ + "\nAn optional description that will appear as subtext underneath the feature name" + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/kibana_feature.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "features", "id": "def-public.KibanaFeatureConfig.category", @@ -882,6 +912,22 @@ "path": "x-pack/plugins/features/common/sub_feature.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "features", + "id": "def-public.SubFeatureConfig.description", + "type": "string", + "tags": [], + "label": "description", + "description": [ + "\nAn optional description that will appear as subtext underneath the sub-feature name" + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/sub_feature.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -1263,7 +1309,7 @@ "label": "config", "description": [], "signature": [ - "Readonly<{ id: string; name: string; category: Readonly<{ id: string; label: string; ariaLabel?: string | undefined; order?: number | undefined; euiIconType?: string | undefined; }>; order?: number | undefined; excludeFromBasePrivileges?: boolean | undefined; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; app: readonly string[]; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: readonly string[] | undefined; cases?: readonly string[] | undefined; privileges: Readonly<{ all: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; read: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }> | null; subFeatures?: readonly Readonly<{ name: string; requireAllSpaces?: boolean | undefined; privilegesTooltip?: string | undefined; privilegeGroups: readonly Readonly<{ groupType: ", + "Readonly<{ id: string; name: string; description?: string | undefined; category: Readonly<{ id: string; label: string; ariaLabel?: string | undefined; order?: number | undefined; euiIconType?: string | undefined; }>; order?: number | undefined; excludeFromBasePrivileges?: boolean | undefined; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; app: readonly string[]; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: readonly string[] | undefined; cases?: readonly string[] | undefined; privileges: Readonly<{ all: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; read: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }> | null; subFeatures?: readonly Readonly<{ name: string; requireAllSpaces?: boolean | undefined; privilegesTooltip?: string | undefined; privilegeGroups: readonly Readonly<{ groupType: ", { "pluginId": "features", "scope": "common", @@ -1271,7 +1317,7 @@ "section": "def-common.SubFeaturePrivilegeGroupType", "text": "SubFeaturePrivilegeGroupType" }, - "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; }>[] | undefined; privilegesTooltip?: string | undefined; reserved?: Readonly<{ description: string; privileges: readonly Readonly<{ id: string; privilege: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }>[]; }> | undefined; }>" + "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; description?: string | undefined; }>[] | undefined; privilegesTooltip?: string | undefined; reserved?: Readonly<{ description: string; privileges: readonly Readonly<{ id: string; privilege: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }>[]; }> | undefined; }>" ], "path": "x-pack/plugins/features/common/kibana_feature.ts", "deprecated": false, @@ -1303,6 +1349,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "features", + "id": "def-server.KibanaFeature.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/kibana_feature.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "features", "id": "def-server.KibanaFeature.order", @@ -1942,6 +2002,22 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "features", + "id": "def-server.KibanaFeatureConfig.description", + "type": "string", + "tags": [], + "label": "description", + "description": [ + "\nAn optional description that will appear as subtext underneath the feature name" + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/kibana_feature.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "features", "id": "def-server.KibanaFeatureConfig.category", @@ -2998,7 +3074,7 @@ "label": "config", "description": [], "signature": [ - "Readonly<{ id: string; name: string; category: Readonly<{ id: string; label: string; ariaLabel?: string | undefined; order?: number | undefined; euiIconType?: string | undefined; }>; order?: number | undefined; excludeFromBasePrivileges?: boolean | undefined; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; app: readonly string[]; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: readonly string[] | undefined; cases?: readonly string[] | undefined; privileges: Readonly<{ all: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; read: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }> | null; subFeatures?: readonly Readonly<{ name: string; requireAllSpaces?: boolean | undefined; privilegesTooltip?: string | undefined; privilegeGroups: readonly Readonly<{ groupType: ", + "Readonly<{ id: string; name: string; description?: string | undefined; category: Readonly<{ id: string; label: string; ariaLabel?: string | undefined; order?: number | undefined; euiIconType?: string | undefined; }>; order?: number | undefined; excludeFromBasePrivileges?: boolean | undefined; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; app: readonly string[]; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: readonly string[] | undefined; cases?: readonly string[] | undefined; privileges: Readonly<{ all: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; read: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }> | null; subFeatures?: readonly Readonly<{ name: string; requireAllSpaces?: boolean | undefined; privilegesTooltip?: string | undefined; privilegeGroups: readonly Readonly<{ groupType: ", { "pluginId": "features", "scope": "common", @@ -3006,7 +3082,7 @@ "section": "def-common.SubFeaturePrivilegeGroupType", "text": "SubFeaturePrivilegeGroupType" }, - "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; }>[] | undefined; privilegesTooltip?: string | undefined; reserved?: Readonly<{ description: string; privileges: readonly Readonly<{ id: string; privilege: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }>[]; }> | undefined; }>" + "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; description?: string | undefined; }>[] | undefined; privilegesTooltip?: string | undefined; reserved?: Readonly<{ description: string; privileges: readonly Readonly<{ id: string; privilege: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }>[]; }> | undefined; }>" ], "path": "x-pack/plugins/features/common/kibana_feature.ts", "deprecated": false, @@ -3038,6 +3114,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "features", + "id": "def-common.KibanaFeature.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/kibana_feature.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "features", "id": "def-common.KibanaFeature.order", @@ -3256,7 +3346,7 @@ "section": "def-common.SubFeaturePrivilegeGroupType", "text": "SubFeaturePrivilegeGroupType" }, - "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; }>" + "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; description?: string | undefined; }>" ], "path": "x-pack/plugins/features/common/sub_feature.ts", "deprecated": false, @@ -3310,6 +3400,17 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "features", + "id": "def-common.SubFeature.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "x-pack/plugins/features/common/sub_feature.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "features", "id": "def-common.SubFeature.toRaw", @@ -3326,7 +3427,7 @@ "section": "def-common.SubFeaturePrivilegeGroupType", "text": "SubFeaturePrivilegeGroupType" }, - "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; }" + "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; description?: string | undefined; }" ], "path": "x-pack/plugins/features/common/sub_feature.ts", "deprecated": false, @@ -3799,6 +3900,22 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "features", + "id": "def-common.KibanaFeatureConfig.description", + "type": "string", + "tags": [], + "label": "description", + "description": [ + "\nAn optional description that will appear as subtext underneath the feature name" + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/kibana_feature.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "features", "id": "def-common.KibanaFeatureConfig.category", @@ -4125,6 +4242,22 @@ "path": "x-pack/plugins/features/common/sub_feature.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "features", + "id": "def-common.SubFeatureConfig.description", + "type": "string", + "tags": [], + "label": "description", + "description": [ + "\nAn optional description that will appear as subtext underneath the sub-feature name" + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/sub_feature.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/features.mdx b/api_docs/features.mdx index dd7525851c6b9..1dee1737a041a 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 227 | 0 | 96 | 2 | +| 236 | 0 | 100 | 2 | ## Client diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index b428144e7ac17..9f8b30c0e19b9 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index d6ffe86db512b..b17f7bf11ffad 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.mdx b/api_docs/files.mdx index c6e33a3ee6465..f215b09505026 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; diff --git a/api_docs/files_management.mdx b/api_docs/files_management.mdx index bc5de1ed3483e..31555b4455c6b 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'filesManagement'] --- import filesManagementObj from './files_management.devdocs.json'; diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index f6310762d63cc..dae0558193bc0 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 9338f458c7c1d..beef1364ad893 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/guided_onboarding.mdx b/api_docs/guided_onboarding.mdx index 8d73c04c337ff..6ce4b28be1781 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.mdx b/api_docs/home.mdx index d5bcac923cca3..120d967c6a880 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/image_embeddable.mdx b/api_docs/image_embeddable.mdx index 23fe22925bcb3..b22c237086fa4 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'imageEmbeddable'] --- import imageEmbeddableObj from './image_embeddable.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 3595f2d107859..c337bae367f5d 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 415f55708a8ef..93c6e92b4a473 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index 5fdac6c64a519..c1603013c869e 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index fc857669932a5..4a1fcb60a3935 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 45c62b5a43b75..6944fc39abe17 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 89ce2f1b62c13..5b95b95d48ea7 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index 92162f213d846..340e05a7cbf70 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 79d6fbf263285..b7b19c6366b5f 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts.mdx b/api_docs/kbn_alerts.mdx index 49e5dc8135ab5..c02f467bd6b96 100644 --- a/api_docs/kbn_alerts.mdx +++ b/api_docs/kbn_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts title: "@kbn/alerts" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts'] --- import kbnAlertsObj from './kbn_alerts.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index 1fc6bffbe3195..20639d149569d 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index d9d55faf98255..b02e9213d3d32 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index db46115f0e4d1..37cfd7cacc304 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 72ea0b3e98d02..5492fab3d131e 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index d18561ef14a7f..57de118630486 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index 9eea8203537c1..cc7c9ddbc79c1 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index 61dc2668e642d..a158f46aa6c6a 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index 3c674f4da3b2a..1b83cbb884035 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index f4c2b892416e7..bb935bc94bb5a 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace_client.mdx b/api_docs/kbn_apm_synthtrace_client.mdx index 28b37a72cdcd9..6519e9feea038 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index 99c9fc2198683..259d75bf8f001 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index e3e0d7c7f9506..1db949dd3b6c2 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.devdocs.json b/api_docs/kbn_cases_components.devdocs.json index 098fcecdffa0d..0d0cf52bf71ea 100644 --- a/api_docs/kbn_cases_components.devdocs.json +++ b/api_docs/kbn_cases_components.devdocs.json @@ -67,9 +67,240 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.Tooltip", + "type": "Function", + "tags": [], + "label": "Tooltip", + "description": [], + "signature": [ + "React.NamedExoticComponent<", + { + "pluginId": "@kbn/cases-components", + "scope": "common", + "docId": "kibKbnCasesComponentsPluginApi", + "section": "def-common.CaseTooltipProps", + "text": "CaseTooltipProps" + }, + "> & { readonly type: React.NamedExoticComponent<", + { + "pluginId": "@kbn/cases-components", + "scope": "common", + "docId": "kibKbnCasesComponentsPluginApi", + "section": "def-common.CaseTooltipProps", + "text": "CaseTooltipProps" + }, + ">; }" + ], + "path": "packages/kbn-cases-components/src/tooltip/tooltip.tsx", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.Tooltip.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + } + ], + "interfaces": [ + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipContentProps", + "type": "Interface", + "tags": [], + "label": "CaseTooltipContentProps", + "description": [], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipContentProps.title", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipContentProps.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipContentProps.status", + "type": "Enum", + "tags": [], + "label": "status", + "description": [], + "signature": [ + { + "pluginId": "@kbn/cases-components", + "scope": "common", + "docId": "kibKbnCasesComponentsPluginApi", + "section": "def-common.CaseStatuses", + "text": "CaseStatuses" + } + ], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipContentProps.totalComments", + "type": "number", + "tags": [], + "label": "totalComments", + "description": [], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipContentProps.createdAt", + "type": "string", + "tags": [], + "label": "createdAt", + "description": [], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipContentProps.createdBy", + "type": "Object", + "tags": [], + "label": "createdBy", + "description": [], + "signature": [ + "{ username?: string | undefined; fullName?: string | undefined; }" + ], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipProps", + "type": "Interface", + "tags": [], + "label": "CaseTooltipProps", + "description": [], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipProps.children", + "type": "CompoundType", + "tags": [], + "label": "children", + "description": [], + "signature": [ + "boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | null | undefined" + ], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipProps.content", + "type": "Object", + "tags": [], + "label": "content", + "description": [], + "signature": [ + { + "pluginId": "@kbn/cases-components", + "scope": "common", + "docId": "kibKbnCasesComponentsPluginApi", + "section": "def-common.CaseTooltipContentProps", + "text": "CaseTooltipContentProps" + } + ], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipProps.dataTestSubj", + "type": "string", + "tags": [], + "label": "dataTestSubj", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipProps.className", + "type": "string", + "tags": [], + "label": "className", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipProps.loading", + "type": "CompoundType", + "tags": [], + "label": "loading", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false } ], - "interfaces": [], "enums": [ { "parentPluginId": "@kbn/cases-components", diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index a7ac016a8cd0c..1383a7a084c4c 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; @@ -21,13 +21,16 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 4 | 0 | 3 | 0 | +| 19 | 0 | 17 | 0 | ## Common ### Functions +### Interfaces + + ### Enums diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index a1539ae62a862..9ccb77e9e7530 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] --- import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index ebc9de6570e4e..d2db6df86e1c1 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index 19cd71ec402dd..1fb428f7bfd86 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index c95ab55e764c8..050646efc62be 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index 21e7a0b5e608d..1e041284ad082 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 201b379196a46..0272b99dc0d5f 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index d42a7c4f450e9..4450424eb9146 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index 2dcc14030248a..15900a4a750f2 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index d7b8e465f3710..963bb0bf55f55 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_editor.mdx b/api_docs/kbn_content_management_content_editor.mdx index f185f228dc375..1ce90777a9265 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list.mdx b/api_docs/kbn_content_management_table_list.mdx index 33d091102189f..09307a9a5e8b3 100644 --- a/api_docs/kbn_content_management_table_list.mdx +++ b/api_docs/kbn_content_management_table_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list title: "@kbn/content-management-table-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list'] --- import kbnContentManagementTableListObj from './kbn_content_management_table_list.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 9075a4046ebd9..a20e9f8a3c5aa 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index 23bf366e80881..7dfc1cd540af3 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index 5e41dbcf8548b..f5557404253ef 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 11b7e7675b286..fd7b8006083ea 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index 6710be7ab0a0e..cf91b8ca6196d 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index 3830bc6058a90..a0b19a767f0b2 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index 3344b64500759..2a399c82ae317 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index 07778d15a720e..5c212de74c01f 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index ff8343c33ebc5..29afa052090f3 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index 830b64c4e35dc..8da709e6fdf74 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index f50691a1bda57..c3796ff08c7f4 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index e4e566c49ec6c..2dc0511e53a6e 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_apps_server_internal.mdx b/api_docs/kbn_core_apps_server_internal.mdx index 62c327188126b..fe7ad49f1c35a 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-server-internal'] --- import kbnCoreAppsServerInternalObj from './kbn_core_apps_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index d1964605418a9..4e8f4094ebc61 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index e531f15c08e0a..cd89760667b73 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index 2a5cef2a3dce0..b72f07dc3db01 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index a0c9cc1dbf9aa..61b5ca8885174 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index 1141f1d5bb316..55630403a7979 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index 0117c869568b8..369ca58e93dbc 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index a7635e2928a47..a168e0a7d17cf 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index 6f1e87e9f2d75..0c78ca87b6f54 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index 097a47105ff32..ad9782c1f33c7 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index 265261bb219c0..2b89597d24af0 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index 6050f6d0c2fcb..bcd2d4cbb802d 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser.mdx b/api_docs/kbn_core_custom_branding_browser.mdx index 7c9a5ea7f308e..6bc4310789592 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser'] --- import kbnCoreCustomBrandingBrowserObj from './kbn_core_custom_branding_browser.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_internal.mdx b/api_docs/kbn_core_custom_branding_browser_internal.mdx index 3e00ffd978395..883a8b4114df5 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-internal'] --- import kbnCoreCustomBrandingBrowserInternalObj from './kbn_core_custom_branding_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_mocks.mdx b/api_docs/kbn_core_custom_branding_browser_mocks.mdx index 27158777d9a40..606f917d87698 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-mocks'] --- import kbnCoreCustomBrandingBrowserMocksObj from './kbn_core_custom_branding_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_common.mdx b/api_docs/kbn_core_custom_branding_common.mdx index 030332a2c7d08..77a74fa813459 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-common'] --- import kbnCoreCustomBrandingCommonObj from './kbn_core_custom_branding_common.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server.mdx b/api_docs/kbn_core_custom_branding_server.mdx index bbe1909925907..183da513a2b92 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server'] --- import kbnCoreCustomBrandingServerObj from './kbn_core_custom_branding_server.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_internal.mdx b/api_docs/kbn_core_custom_branding_server_internal.mdx index af6ac5230e77b..013ecebe3b5ad 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-internal'] --- import kbnCoreCustomBrandingServerInternalObj from './kbn_core_custom_branding_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_mocks.mdx b/api_docs/kbn_core_custom_branding_server_mocks.mdx index 05012af21c1e9..b8ecb5935e649 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-mocks'] --- import kbnCoreCustomBrandingServerMocksObj from './kbn_core_custom_branding_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index 3f93fade451f8..7725e72b796e2 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index 03d27c8ef49f9..e052464f84e8b 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index 39e696e87e051..2a30857093ccb 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index 3d67fe52205e0..e29ade1fef42c 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index d53b102a1de28..66f16160cd23d 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index c44f7ed32bc9c..fff8b8004aaab 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index a3fdb524b0d3a..a762f3f3e6882 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index e467ef10f36d4..416b2979acad8 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index 47de5c9d4fcca..5a265902076e9 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index d61e54b25a79e..be24bb8e16b1c 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index 302b5650018dc..2f0777515d674 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index 179801d9950ad..f0b4b587da614 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index 5058f69647811..a7563f1802b72 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index d1feaef5e39bd..cb1080d43cb14 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index 011e2a47980cc..e09c279ec461d 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index 20cddbb313528..955ee445f9995 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index 29d4da4b16f43..472b0b5ccc1b9 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index 1f8acf0a90ee7..c13b75a9f2da4 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index 9452129737480..4e540508c7bb5 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index 2e7d9e5c6b8ee..c4e5788d55367 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index 81d79d245aefa..7c77a10d2711e 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index 54b7890ea4e85..44c88de8f84a8 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index 6d2e49e5b6a35..c6fcc3f352689 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index c1ec134e944e1..7765d5b30d751 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index 62789a31d5699..9a77d31cc8e59 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index 490019399dac1..3a0a45182fbd1 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index 78afb6bfe5544..ffd424441e1d0 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index e0edc6eeef931..ee2d03ab82b63 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index 2ef9bee274bde..f96855ef9dc75 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index b3f43529d85cc..5372de82f3d22 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index 17ea8a8a32dea..5bf41ab4e30b0 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index 18669fd96c5c0..e2590f15a815c 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_request_handler_context_server.mdx b/api_docs/kbn_core_http_request_handler_context_server.mdx index 2972cbc7ef089..bd75e3445c598 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-request-handler-context-server'] --- import kbnCoreHttpRequestHandlerContextServerObj from './kbn_core_http_request_handler_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server.mdx b/api_docs/kbn_core_http_resources_server.mdx index ba7408ad04d22..b2575105ac9c6 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server'] --- import kbnCoreHttpResourcesServerObj from './kbn_core_http_resources_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_internal.mdx b/api_docs/kbn_core_http_resources_server_internal.mdx index 1b1c8aa71f223..1f2482afeff63 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-internal'] --- import kbnCoreHttpResourcesServerInternalObj from './kbn_core_http_resources_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_mocks.mdx b/api_docs/kbn_core_http_resources_server_mocks.mdx index 99e1a096c1312..456c88de99e28 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-mocks'] --- import kbnCoreHttpResourcesServerMocksObj from './kbn_core_http_resources_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index 02b2c661748ea..35f035dc528ad 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index 69dd0d060beac..eb9a5332d7540 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 3190372b67fa3..8f0d54c59f90f 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index cda612dede365..58c8e413baf0b 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.devdocs.json b/api_docs/kbn_core_http_server_mocks.devdocs.json index 3e64bb2af2e99..03dcec7536ef2 100644 --- a/api_docs/kbn_core_http_server_mocks.devdocs.json +++ b/api_docs/kbn_core_http_server_mocks.devdocs.json @@ -886,7 +886,9 @@ "IncomingMessage", "; res: ", "ServerResponse", - "; }> | undefined; readonly route?: ", + "<", + "IncomingMessage", + ">; }> | undefined; readonly route?: ", { "pluginId": "@kbn/utility-types", "scope": "common", diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index 57139f365c64c..74bb1cf8de8c7 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index 54eb410b3d307..de5cb71f971ef 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] --- import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index 5fae19e7314d1..546afc9f715eb 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] --- import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server.mdx b/api_docs/kbn_core_i18n_server.mdx index d4c6c6e4c4fa9..c3b532bc5ffab 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server'] --- import kbnCoreI18nServerObj from './kbn_core_i18n_server.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_internal.mdx b/api_docs/kbn_core_i18n_server_internal.mdx index aee1f699a920f..6190756d94540 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-internal'] --- import kbnCoreI18nServerInternalObj from './kbn_core_i18n_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_mocks.mdx b/api_docs/kbn_core_i18n_server_mocks.mdx index 2b63423a058ba..e177326189512 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-mocks'] --- import kbnCoreI18nServerMocksObj from './kbn_core_i18n_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index 5bd54f6f92ba1..85d59b760de15 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] --- import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx index 94b8743da1160..41956983980e7 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal'] --- import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx index fa07ca535a1b9..f2b92bf299b73 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks'] --- import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index 032ee18ffea5f..c3fa9de8f5ec8 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser'] --- import kbnCoreLifecycleBrowserObj from './kbn_core_lifecycle_browser.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser_mocks.mdx b/api_docs/kbn_core_lifecycle_browser_mocks.mdx index d78b0b193ba03..6dabcd528a50d 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser-mocks'] --- import kbnCoreLifecycleBrowserMocksObj from './kbn_core_lifecycle_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server.mdx b/api_docs/kbn_core_lifecycle_server.mdx index 7b24fcf0fe916..263138ba9bdda 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server'] --- import kbnCoreLifecycleServerObj from './kbn_core_lifecycle_server.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server_mocks.mdx b/api_docs/kbn_core_lifecycle_server_mocks.mdx index 7d053ffdbdf35..c5f44e04c9420 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server-mocks'] --- import kbnCoreLifecycleServerMocksObj from './kbn_core_lifecycle_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_browser_mocks.mdx b/api_docs/kbn_core_logging_browser_mocks.mdx index 96cca3f964398..1f6fb9346f70a 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-browser-mocks'] --- import kbnCoreLoggingBrowserMocksObj from './kbn_core_logging_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_common_internal.mdx b/api_docs/kbn_core_logging_common_internal.mdx index 42ea81f914c5c..313b37477b530 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-common-internal'] --- import kbnCoreLoggingCommonInternalObj from './kbn_core_logging_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index 85b07b6f2dd52..ddbcd3010e164 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] --- import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index 7064852da0ca2..de392e214465e 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] --- import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index 1874450c88117..3106e8c3de66c 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] --- import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx index ed94a6435f9ba..e07daaba8f54f 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal'] --- import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx index ba09fcb7976f0..b83f0957c217a 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks'] --- import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx index 032538900e9e5..73b620be14886 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server'] --- import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx index 20f02a5a9f190..ea9246b2b07d5 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal'] --- import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx index 1097e49d3635e..a59ea081e17ca 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks'] --- import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx index f287628c3640e..5237821584191 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser'] --- import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json'; diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx index c1206a4e0f7fd..bc28583413524 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server'] --- import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx index 77d696b39bfa9..b2a98d5704fd7 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal'] --- import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx index 2a05d5a33c378..c83a0cda2501a 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks'] --- import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index e2e4e8b17c09a..d9dac783cec14 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser'] --- import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx index 671634599ef80..9da3625423420 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal'] --- import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx index f074189adec0c..b9ecdfc7751e3 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks'] --- import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx index 46ffdd6e24967..c6e6a665885c7 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser'] --- import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx index e7a24d90d2c63..98079ea1e6b46 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal'] --- import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx index bafa5a832e109..8108494b00c90 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks'] --- import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser.mdx b/api_docs/kbn_core_plugins_browser.mdx index 7d2b8f9ec2e0c..d01bf2baef294 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser'] --- import kbnCorePluginsBrowserObj from './kbn_core_plugins_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser_mocks.mdx b/api_docs/kbn_core_plugins_browser_mocks.mdx index 66a3842aceb31..777e9d238e683 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index c524208ebd75b..e05cb04898b8b 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server'] --- import kbnCorePluginsServerObj from './kbn_core_plugins_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server_mocks.mdx b/api_docs/kbn_core_plugins_server_mocks.mdx index 44d3029c95623..441d591bebcf4 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server-mocks'] --- import kbnCorePluginsServerMocksObj from './kbn_core_plugins_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index 4b6f25752cd70..b9d31dc75058b 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server'] --- import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx index b675ce3a9b3e6..074104605e4c7 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index aa3687447d230..fbce8ff25a578 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-browser-mocks'] --- import kbnCoreRenderingBrowserMocksObj from './kbn_core_rendering_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_internal.mdx b/api_docs/kbn_core_rendering_server_internal.mdx index 32a90ccd5bbaf..ac788fd89acb9 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-internal'] --- import kbnCoreRenderingServerInternalObj from './kbn_core_rendering_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_mocks.mdx b/api_docs/kbn_core_rendering_server_mocks.mdx index e32139c07ec93..353f961c17c59 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-mocks'] --- import kbnCoreRenderingServerMocksObj from './kbn_core_rendering_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_root_server_internal.mdx b/api_docs/kbn_core_root_server_internal.mdx index 3bf63e8aa6a78..e0f0cfcfd7f35 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-root-server-internal'] --- import kbnCoreRootServerInternalObj from './kbn_core_root_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index 3f85321452540..c88269bf11998 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index 3487bc8ef15ec..1a2df544e05a6 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_internal.mdx b/api_docs/kbn_core_saved_objects_api_server_internal.mdx index 1447ae26472d6..8639ebdc3695d 100644 --- a/api_docs/kbn_core_saved_objects_api_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-internal title: "@kbn/core-saved-objects-api-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-internal'] --- import kbnCoreSavedObjectsApiServerInternalObj from './kbn_core_saved_objects_api_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx index d87a78da3ea0f..2bd563246fb9f 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-mocks'] --- import kbnCoreSavedObjectsApiServerMocksObj from './kbn_core_saved_objects_api_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.mdx b/api_docs/kbn_core_saved_objects_base_server_internal.mdx index b535eb8d93519..18ce469e77872 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-internal'] --- import kbnCoreSavedObjectsBaseServerInternalObj from './kbn_core_saved_objects_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx index 40ccc4cd94c2e..39ebf7912e864 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-mocks'] --- import kbnCoreSavedObjectsBaseServerMocksObj from './kbn_core_saved_objects_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx index 85b708fc261cb..1fd9db3b76d42 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser'] --- import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx index 931ac94fd2014..0706ece98d2bc 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal'] --- import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index 61413666e4f67..a9c7379266a68 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index 31feba63325b3..b31ce7c861179 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common'] --- import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx index 219d98f4f60a5..c92bb074e7a30 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-internal'] --- import kbnCoreSavedObjectsImportExportServerInternalObj from './kbn_core_saved_objects_import_export_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx index 5ff515d5369b5..2513ceec8ecee 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-mocks'] --- import kbnCoreSavedObjectsImportExportServerMocksObj from './kbn_core_saved_objects_import_export_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx index 8818ae03fadb9..abf3810840457 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-internal'] --- import kbnCoreSavedObjectsMigrationServerInternalObj from './kbn_core_saved_objects_migration_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx index 7d47b42569327..7dd0192cc1b87 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-mocks'] --- import kbnCoreSavedObjectsMigrationServerMocksObj from './kbn_core_saved_objects_migration_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index b44405f4a08ea..75c7047b9ed67 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server'] --- import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_internal.mdx b/api_docs/kbn_core_saved_objects_server_internal.mdx index 9d41f0e285cc3..fad9f8a7b25f4 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-internal'] --- import kbnCoreSavedObjectsServerInternalObj from './kbn_core_saved_objects_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_mocks.mdx b/api_docs/kbn_core_saved_objects_server_mocks.mdx index 013f3c5fa49a7..1bf3921e97e5d 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-mocks'] --- import kbnCoreSavedObjectsServerMocksObj from './kbn_core_saved_objects_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_utils_server.mdx b/api_docs/kbn_core_saved_objects_utils_server.mdx index 2c97fb48e626a..b54f4ead918bc 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index e8e437bf2b7d3..cfad4d9b5fa97 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common'] --- import kbnCoreStatusCommonObj from './kbn_core_status_common.devdocs.json'; diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index 4eb221c19e942..64ca53dc9e25d 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index aebf6da5d736f..bb8c4f84b4de0 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server'] --- import kbnCoreStatusServerObj from './kbn_core_status_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_internal.mdx b/api_docs/kbn_core_status_server_internal.mdx index 949c0ad0593e0..aabf7772e2923 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-internal'] --- import kbnCoreStatusServerInternalObj from './kbn_core_status_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_mocks.mdx b/api_docs/kbn_core_status_server_mocks.mdx index ae1637bf54235..39be35691328a 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-mocks'] --- import kbnCoreStatusServerMocksObj from './kbn_core_status_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx index a0a7d27b0d618..b70ff69f57b35 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters'] --- import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx index 8a26c0379d3eb..7e3c8455ca8f3 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser'] --- import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_kbn_server.mdx b/api_docs/kbn_core_test_helpers_kbn_server.mdx index 892396842504c..aebb7d2e48094 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index c14764a75db47..343f9c20c51bf 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-so-type-serializer'] --- import kbnCoreTestHelpersSoTypeSerializerObj from './kbn_core_test_helpers_so_type_serializer.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_test_utils.mdx b/api_docs/kbn_core_test_helpers_test_utils.mdx index 35f11f17d846d..ec3395e709bb2 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-test-utils'] --- import kbnCoreTestHelpersTestUtilsObj from './kbn_core_test_helpers_test_utils.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index 14c773043d48f..8a1c75f66698b 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index c74fc821a6987..0b027bbb83c27 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index 9faea7c87fd3e..9548cb4e6da0e 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] --- import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx index 7c1a6a0be2515..6307b046d66ed 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser'] --- import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx index 89e0f3e5fde37..1405c952237f3 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal'] --- import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx index ae926ac00270c..f704f8861bfa7 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks'] --- import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx index fe7a76a4d0476..ca35f69a29717 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common'] --- import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server.mdx b/api_docs/kbn_core_ui_settings_server.mdx index 4272333016152..7d926327aec1a 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server'] --- import kbnCoreUiSettingsServerObj from './kbn_core_ui_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_internal.mdx b/api_docs/kbn_core_ui_settings_server_internal.mdx index f540e37698f08..efce399b6387a 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-internal'] --- import kbnCoreUiSettingsServerInternalObj from './kbn_core_ui_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_mocks.mdx b/api_docs/kbn_core_ui_settings_server_mocks.mdx index 4c6bb8eadd2ba..064fc43986987 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-mocks'] --- import kbnCoreUiSettingsServerMocksObj from './kbn_core_ui_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server.mdx b/api_docs/kbn_core_usage_data_server.mdx index 858af51d296d0..32b862453c5c9 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server'] --- import kbnCoreUsageDataServerObj from './kbn_core_usage_data_server.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_internal.mdx b/api_docs/kbn_core_usage_data_server_internal.mdx index 47c86bba33da5..78c35be8d2b93 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-internal'] --- import kbnCoreUsageDataServerInternalObj from './kbn_core_usage_data_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_mocks.mdx b/api_docs/kbn_core_usage_data_server_mocks.mdx index e7ae8f38a9dd3..453bf061ea015 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index 980e17a305d80..ee6c19dd69594 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] --- import kbnCryptoObj from './kbn_crypto.devdocs.json'; diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx index 3e95b8255e6a6..c827cd4561840 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index a8bc6cb697ded..4f638de74c127 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index e2c155171baad..9dfb5388b6e42 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index 97e100f8bebab..2778231aaec55 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] --- import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index 496c4c2ec9c69..2dd89ad16bdd8 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] --- import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index 308cd347b3246..a7636942acda7 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] --- import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index d68a13fddb31d..cea0719a9a636 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 17cd0fab07b51..5c1279a2ddbcf 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index ee99751554909..5a8e90548ea72 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index bb232cfa477d6..f7279b5b1b5a9 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs.mdx b/api_docs/kbn_ecs.mdx index 80bb17829ff4a..88c6669c81852 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 3ff3808c5ea87..1cd1241e72020 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es'] --- import kbnEsObj from './kbn_es.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index 4c10ca013a9aa..3871a67bcaa01 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] --- import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json'; diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx index c84601e8a6ff9..cf3b6246ed16a 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors'] --- import kbnEsErrorsObj from './kbn_es_errors.devdocs.json'; diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index 62ac53ebd09b3..fac2d5468a936 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index a62edc7709d56..94f159886adda 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] --- import kbnEsTypesObj from './kbn_es_types.devdocs.json'; diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index 65215a658a01e..11425a42c525e 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index db4864aea9f0e..444ad17a268ea 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index d0accea503292..493a9424caf54 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 80012c572feac..8331cdecf359f 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 124961ea23078..5278da727fe22 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_get_repo_files.mdx b/api_docs/kbn_get_repo_files.mdx index dee9575b6c5cd..0667f2f59db7d 100644 --- a/api_docs/kbn_get_repo_files.mdx +++ b/api_docs/kbn_get_repo_files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-get-repo-files title: "@kbn/get-repo-files" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/get-repo-files plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/get-repo-files'] --- import kbnGetRepoFilesObj from './kbn_get_repo_files.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index f52b9eac1929a..ca8b60cec723b 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/guided-onboarding'] --- import kbnGuidedOnboardingObj from './kbn_guided_onboarding.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index da8d8d14e0799..ebb147216a916 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.devdocs.json b/api_docs/kbn_hapi_mocks.devdocs.json index b6bc88b0ceafc..ea6ed36bfa580 100644 --- a/api_docs/kbn_hapi_mocks.devdocs.json +++ b/api_docs/kbn_hapi_mocks.devdocs.json @@ -248,7 +248,9 @@ "IncomingMessage", "; res: ", "ServerResponse", - "; }> | undefined; readonly route?: ", + "<", + "IncomingMessage", + ">; }> | undefined; readonly route?: ", { "pluginId": "@kbn/utility-types", "scope": "common", diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index 1bda64b8fdbe6..4a78887e481ec 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_health_gateway_server.mdx b/api_docs/kbn_health_gateway_server.mdx index 1804f853e9905..8e6c006b602cc 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/health-gateway-server'] --- import kbnHealthGatewayServerObj from './kbn_health_gateway_server.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index da88733531039..05a0652a93394 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index fbb0cca46013e..a0adb2ebeb134 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index e2944652e1628..0d032d65c8bbc 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_i18n_react.mdx b/api_docs/kbn_i18n_react.mdx index 54d5cbd63ae8a..bc693d547cb77 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n-react'] --- import kbnI18nReactObj from './kbn_i18n_react.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index b86259e0735c6..631e66e5526fd 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index 68ec1d406634c..fdee8228580c7 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index dc5d9ce593271..5e24cf172f388 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index f0b7343942e4b..fb3ac9d3269c9 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_journeys.mdx b/api_docs/kbn_journeys.mdx index 612b56aaf6797..ac5d2f4c93078 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/journeys'] --- import kbnJourneysObj from './kbn_journeys.devdocs.json'; diff --git a/api_docs/kbn_json_ast.mdx b/api_docs/kbn_json_ast.mdx index 290b57c610bbc..f9abb342f5460 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index fecadec9558ea..9798957315147 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index b520ff3775e38..f8ed3a7159d47 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index eb27c89613efb..7828be038bea0 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index 13012665f6c93..b7ab761147878 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index 3a2c5607dae47..9b80fe0e7ff69 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index 843e635a6bb60..a921e32e6dbae 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index c0663bc16673f..50d75602e83a8 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_date_picker.mdx b/api_docs/kbn_ml_date_picker.mdx index 5828619545b28..a7d85207967aa 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-picker'] --- import kbnMlDatePickerObj from './kbn_ml_date_picker.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index 106a805394d72..390749b7ec1e1 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-defined'] --- import kbnMlIsDefinedObj from './kbn_ml_is_defined.devdocs.json'; diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index 26d567eb7b03b..e1b2128ec8287 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_local_storage.mdx b/api_docs/kbn_ml_local_storage.mdx index 25aaa944c1494..efdd33b039134 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-local-storage'] --- import kbnMlLocalStorageObj from './kbn_ml_local_storage.devdocs.json'; diff --git a/api_docs/kbn_ml_nested_property.mdx b/api_docs/kbn_ml_nested_property.mdx index acef7e71464eb..53c553077041d 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-nested-property'] --- import kbnMlNestedPropertyObj from './kbn_ml_nested_property.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index 2c17d0c6d9176..890726df5ea70 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-query-utils'] --- import kbnMlQueryUtilsObj from './kbn_ml_query_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index c83775cba0f5a..ddd706c6d80dd 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index f730f0ab3d2f1..47d5c587e0c33 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index f6000e78f0cf1..fd951fba1eb5e 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 77b6c501e2787..4afef6c1cb196 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index d543bdf8adba1..fde177b5de6f7 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_osquery_io_ts_types.mdx b/api_docs/kbn_osquery_io_ts_types.mdx index 02ec18d4bd1cc..72e19743a9cd6 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 0f41ab75f3956..ac63fff1084b6 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 56551b21948e6..973415f94b17d 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index 8e9efd729283a..26b4deef4e067 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index 9982f80c880c1..45c3203843779 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index a59643901b9cb..d64ccf7e7977d 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-file-maps'] --- import kbnRepoFileMapsObj from './kbn_repo_file_maps.devdocs.json'; diff --git a/api_docs/kbn_repo_linter.mdx b/api_docs/kbn_repo_linter.mdx index d0c2d3e8fe5f3..34469ade3c69e 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-linter'] --- import kbnRepoLinterObj from './kbn_repo_linter.devdocs.json'; diff --git a/api_docs/kbn_repo_path.mdx b/api_docs/kbn_repo_path.mdx index 50abc5a896b00..26d7842c0dcb5 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-path'] --- import kbnRepoPathObj from './kbn_repo_path.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index 0968fc0bb4999..d43ce5536b441 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index c7fdc0dcf3dae..cf1709dcdd0e2 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index d1e2120680eb5..f3d12996b6f2f 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.devdocs.json b/api_docs/kbn_securitysolution_autocomplete.devdocs.json index 5f57ad28f5f73..365830c784ff3 100644 --- a/api_docs/kbn_securitysolution_autocomplete.devdocs.json +++ b/api_docs/kbn_securitysolution_autocomplete.devdocs.json @@ -842,7 +842,7 @@ "label": "smallLists", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]" ], "path": "packages/kbn-securitysolution-autocomplete/src/field_value_lists/index.tsx", "deprecated": false, @@ -856,7 +856,7 @@ "label": "largeLists", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]" ], "path": "packages/kbn-securitysolution-autocomplete/src/field_value_lists/index.tsx", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index ede4bc08f7f0b..ec2a7e89bcb17 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index 6f2350db36ac3..c6df175c945ab 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_exception_list_components.devdocs.json b/api_docs/kbn_securitysolution_exception_list_components.devdocs.json index 83973455bda55..6e10def35b04f 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.devdocs.json +++ b/api_docs/kbn_securitysolution_exception_list_components.devdocs.json @@ -721,7 +721,7 @@ "label": "item", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-exception-list-components/src/exception_item_card/header/index.tsx", "deprecated": false, @@ -788,7 +788,7 @@ "label": "item", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-exception-list-components/src/exception_item_card/meta/index.tsx", "deprecated": false, @@ -904,7 +904,7 @@ "label": "exceptionItem", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-exception-list-components/src/exception_item_card/exception_item_card.tsx", "deprecated": false, @@ -1095,7 +1095,7 @@ "label": "onEditException", "description": [], "signature": [ - "(item: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void" + "(item: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void" ], "path": "packages/kbn-securitysolution-exception-list-components/src/exception_item_card/exception_item_card.tsx", "deprecated": false, @@ -1109,7 +1109,7 @@ "label": "item", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-exception-list-components/src/exception_item_card/exception_item_card.tsx", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_exception_list_components.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index bcea54351858b..b1db1199786a0 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index b3cfa202e3f73..dafdb0bf90124 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index 7f1fcd13c49ab..04c8f63fce960 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json b/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json index 9bcbaf8108ab8..f54dfcd7e0da2 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json +++ b/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json @@ -27,7 +27,7 @@ "label": "updateExceptionListItemValidate", "description": [], "signature": [ - "(schema: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" + "(schema: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -41,7 +41,7 @@ "label": "schema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -60,7 +60,7 @@ "label": "validateComments", "description": [], "signature": [ - "(item: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" + "(item: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -74,7 +74,7 @@ "label": "item", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -162,7 +162,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false, @@ -718,7 +718,7 @@ "label": "exceptions", "description": [], "signature": [ - "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" + "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false, @@ -1589,7 +1589,7 @@ "label": "exceptions", "description": [], "signature": [ - "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" + "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false, @@ -1847,7 +1847,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false, @@ -1945,7 +1945,7 @@ "label": "exceptions", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false, @@ -2617,7 +2617,7 @@ "label": "CreateEndpointListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"os_types\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"os_types\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_endpoint_list_item_schema/index.ts", "deprecated": false, @@ -2647,7 +2647,7 @@ "label": "CreateExceptionListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_exception_list_item_schema/index.ts", "deprecated": false, @@ -2662,7 +2662,7 @@ "label": "CreateExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_exception_list_item_schema/index.ts", "deprecated": false, @@ -2737,7 +2737,7 @@ "label": "CreateListSchema", "description": [], "signature": [ - "{ description: string; name: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; } & { deserializer?: string | undefined; id?: string | undefined; meta?: object | undefined; serializer?: string | undefined; version?: number | undefined; }" + "{ description: string; name: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; } & { deserializer?: string | undefined; id?: string | undefined; meta?: object | undefined; serializer?: string | undefined; version?: number | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_list_schema/index.ts", "deprecated": false, @@ -2752,7 +2752,7 @@ "label": "CreateListSchemaDecoded", "description": [], "signature": [ - "{ name: string; description: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; id: string | undefined; meta: object | undefined; serializer: string | undefined; deserializer: string | undefined; } & { version: number; }" + "{ name: string; description: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; id: string | undefined; meta: object | undefined; serializer: string | undefined; deserializer: string | undefined; } & { version: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_list_schema/index.ts", "deprecated": false, @@ -2767,7 +2767,7 @@ "label": "CreateRuleExceptionListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; list_id?: undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; list_id?: undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_rule_exception_item_schema/index.ts", "deprecated": false, @@ -2782,7 +2782,7 @@ "label": "CreateRuleExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; list_id: undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; list_id: undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_rule_exception_item_schema/index.ts", "deprecated": false, @@ -3097,7 +3097,7 @@ "label": "EntriesArray", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries/index.ts", "deprecated": false, @@ -3112,7 +3112,7 @@ "label": "EntriesArrayOrUndefined", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[] | undefined" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[] | undefined" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries/index.ts", "deprecated": false, @@ -3127,7 +3127,7 @@ "label": "Entry", "description": [], "signature": [ - "{ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }" + "{ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries/index.ts", "deprecated": false, @@ -3157,7 +3157,7 @@ "label": "EntryList", "description": [], "signature": [ - "{ field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; }" + "{ field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries_list/index.ts", "deprecated": false, @@ -3247,7 +3247,7 @@ "label": "ExceptionListItemSchema", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/exception_list_item_schema/index.ts", "deprecated": false, @@ -3592,7 +3592,7 @@ "label": "FoundAllListItemsSchema", "description": [], "signature": [ - "{ data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; total: number; }" + "{ data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; total: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_all_list_items_schema/index.ts", "deprecated": false, @@ -3607,7 +3607,7 @@ "label": "FoundExceptionListItemSchema", "description": [], "signature": [ - "{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }" + "{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_exception_list_item_schema/index.ts", "deprecated": false, @@ -3637,7 +3637,7 @@ "label": "FoundListItemSchema", "description": [], "signature": [ - "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; }" + "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_list_item_schema/index.ts", "deprecated": false, @@ -3652,7 +3652,7 @@ "label": "FoundListsBySizeSchema", "description": [], "signature": [ - "{ largeLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; smallLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; }" + "{ largeLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; smallLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_lists_by_size_schema/index.ts", "deprecated": false, @@ -3667,7 +3667,7 @@ "label": "FoundListSchema", "description": [], "signature": [ - "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }" + "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_list_schema/index.ts", "deprecated": false, @@ -3682,7 +3682,7 @@ "label": "GetExceptionFilterSchema", "description": [], "signature": [ - "({ exception_list_ids: { exception_list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; type: \"exception_list_ids\"; } | { exceptions: ({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]; type: \"exception_items\"; }) & { alias?: string | undefined; chunk_size?: number | undefined; exclude_exceptions?: boolean | undefined; }" + "({ exception_list_ids: { exception_list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; type: \"exception_list_ids\"; } | { exceptions: ({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]; type: \"exception_items\"; }) & { alias?: string | undefined; chunk_size?: number | undefined; exclude_exceptions?: boolean | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/get_exception_filter_schema/index.ts", "deprecated": false, @@ -3802,7 +3802,7 @@ "label": "ImportExceptionListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_exception_item_schema/index.ts", "deprecated": false, @@ -3817,7 +3817,7 @@ "label": "ImportExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_exception_item_schema/index.ts", "deprecated": false, @@ -3877,7 +3877,7 @@ "label": "ImportListItemQuerySchema", "description": [], "signature": [ - "{ deserializer: string | undefined; list_id: string | undefined; serializer: string | undefined; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined; }" + "{ deserializer: string | undefined; list_id: string | undefined; serializer: string | undefined; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_list_item_query_schema/index.ts", "deprecated": false, @@ -3892,7 +3892,7 @@ "label": "ImportListItemQuerySchemaEncoded", "description": [], "signature": [ - "{ deserializer?: string | undefined; list_id?: string | undefined; serializer?: string | undefined; type?: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined; }" + "{ deserializer?: string | undefined; list_id?: string | undefined; serializer?: string | undefined; type?: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_list_item_query_schema/index.ts", "deprecated": false, @@ -4042,7 +4042,7 @@ "label": "ListArraySchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_schema/index.ts", "deprecated": false, @@ -4087,7 +4087,7 @@ "label": "ListItemArraySchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]" + "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_item_schema/index.ts", "deprecated": false, @@ -4117,7 +4117,7 @@ "label": "ListItemSchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }" + "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_item_schema/index.ts", "deprecated": false, @@ -4147,7 +4147,7 @@ "label": "ListSchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_schema/index.ts", "deprecated": false, @@ -4372,7 +4372,7 @@ "label": "NonEmptyEntriesArray", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/non_empty_entries_array/index.ts", "deprecated": false, @@ -4387,7 +4387,7 @@ "label": "NonEmptyEntriesArrayDecoded", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/non_empty_entries_array/index.ts", "deprecated": false, @@ -4822,7 +4822,7 @@ "label": "SearchListItemArraySchema", "description": [], "signature": [ - "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]" + "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/search_list_item_schema/index.ts", "deprecated": false, @@ -4837,7 +4837,7 @@ "label": "SearchListItemSchema", "description": [], "signature": [ - "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }" + "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/search_list_item_schema/index.ts", "deprecated": false, @@ -5002,7 +5002,7 @@ "label": "Type", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"" + "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/type/index.ts", "deprecated": false, @@ -5017,7 +5017,7 @@ "label": "TypeOrUndefined", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined" + "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/type/index.ts", "deprecated": false, @@ -5077,7 +5077,7 @@ "label": "UpdateEndpointListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_endpoint_list_item_schema/index.ts", "deprecated": false, @@ -5092,7 +5092,7 @@ "label": "UpdateEndpointListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_endpoint_list_item_schema/index.ts", "deprecated": false, @@ -5107,7 +5107,7 @@ "label": "UpdateExceptionListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_schema/index.ts", "deprecated": false, @@ -5122,7 +5122,7 @@ "label": "UpdateExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"namespace_type\" | \"os_types\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"namespace_type\" | \"os_types\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_schema/index.ts", "deprecated": false, @@ -5677,7 +5677,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; list_id: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; list_id: ", "Type", "; name: ", "StringC", @@ -5845,7 +5845,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; name: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; name: ", "StringC", "; type: ", "KeyofC", @@ -7252,7 +7252,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; list_id: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; list_id: ", "Type", "; name: ", "StringC", @@ -8521,7 +8521,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; list_id: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; list_id: ", "Type", "; name: ", "StringC", @@ -8808,7 +8808,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; item_id: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; item_id: ", "Type", "; list_id: ", "Type", @@ -9848,7 +9848,7 @@ ], "signature": [ "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>" + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/non_empty_entries_array/index.ts", "deprecated": false, @@ -10858,7 +10858,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; name: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; name: ", "StringC", "; type: ", "KeyofC", @@ -10912,7 +10912,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; name: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; name: ", "StringC", "; type: ", "KeyofC", diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index 1bd796399f6f6..84abef50d74cd 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index 3a881196872e9..2caed79022855 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index 7afc0b1ca2a95..0f1200f62d772 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.devdocs.json b/api_docs/kbn_securitysolution_list_api.devdocs.json index cd8334e742dda..44699631fbffc 100644 --- a/api_docs/kbn_securitysolution_list_api.devdocs.json +++ b/api_docs/kbn_securitysolution_list_api.devdocs.json @@ -82,7 +82,7 @@ "section": "def-common.AddExceptionListItemProps", "text": "AddExceptionListItemProps" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -270,7 +270,7 @@ "section": "def-common.ApiCallByIdProps", "text": "ApiCallByIdProps" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -317,7 +317,7 @@ "section": "def-common.DeleteListParams", "text": "DeleteListParams" }, - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -509,7 +509,7 @@ "section": "def-common.ApiCallByIdProps", "text": "ApiCallByIdProps" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -556,7 +556,7 @@ "section": "def-common.ApiCallByListIdProps", "text": "ApiCallByListIdProps" }, - ") => Promise<{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }>" + ") => Promise<{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -650,7 +650,7 @@ "section": "def-common.FindListsParams", "text": "FindListsParams" }, - ") => Promise<{ largeLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; smallLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; }>" + ") => Promise<{ largeLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; smallLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -697,7 +697,7 @@ "section": "def-common.FindListsParams", "text": "FindListsParams" }, - ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" + ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -862,7 +862,7 @@ "section": "def-common.ImportListParams", "text": "ImportListParams" }, - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -1072,7 +1072,7 @@ "section": "def-common.UpdateExceptionListItemProps", "text": "UpdateExceptionListItemProps" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -1471,7 +1471,7 @@ "label": "type", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined" + "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/types.ts", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index 662edc191a6db..5caaeaf4662eb 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index 602d3b1f123df..fa9092037f8fe 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.devdocs.json b/api_docs/kbn_securitysolution_list_hooks.devdocs.json index befcfaaecfb13..a9290e1b6ed6b 100644 --- a/api_docs/kbn_securitysolution_list_hooks.devdocs.json +++ b/api_docs/kbn_securitysolution_list_hooks.devdocs.json @@ -29,7 +29,7 @@ "\nThis adds an id to the incoming exception item entries as ReactJS prefers to have\nan id added to them for use as a stable id. Later if we decide to change the data\nmodel to have id's within the array then this code should be removed. If not, then\nthis code should stay as an adapter for ReactJS.\n\nThis does break the type system slightly as we are lying a bit to the type system as we return\nthe same exceptionItem as we have previously but are augmenting the arrays with an id which TypeScript\ndoesn't mind us doing here. However, downstream you will notice that you have an id when the type\ndoes not indicate it. In that case use (ExceptionItem & { id: string }) temporarily if you're using the id. If you're not,\nyou can ignore the id and just use the normal TypeScript with ReactJS.\n" ], "signature": [ - "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -45,7 +45,7 @@ "The exceptionItem to add an id to the threat matches." ], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -68,7 +68,7 @@ "\nThis removes createdAt, createdBy from the exceptionItem if a comment was added to\nthe Exception item, and return the comment message with id to prevent creating the commet\ntwice" ], "signature": [ - "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })) => { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })) => { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -84,7 +84,7 @@ "The exceptionItem to remove createdAt, createdBy from the comments array." ], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -107,7 +107,7 @@ "\nThis removes an id from the exceptionItem entries as ReactJS prefers to have\nan id added to them for use as a stable id. Later if we decide to change the data\nmodel to have id's within the array then this code should be removed. If not, then\nthis code should stay as an adapter for ReactJS.\n" ], "signature": [ - "(exceptionItem: T) => T" + "(exceptionItem: T) => T" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -146,7 +146,7 @@ "\nTransforms the output of rules to compensate for technical debt or UI concerns such as\nReactJS preferences for having ids within arrays if the data is not modeled that way.\n\nIf you add a new transform of the input called \"myNewTransform\" do it\nin the form of:\nflow(addIdToExceptionItemEntries, myNewTransform)(exceptionItem)\n" ], "signature": [ - "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -162,7 +162,7 @@ "The exceptionItem to transform the output of" ], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -183,7 +183,7 @@ "label": "transformNewItemOutput", "description": [], "signature": [ - "(exceptionItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "(exceptionItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -197,7 +197,7 @@ "label": "exceptionItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -218,7 +218,7 @@ "\nTransforms the output of exception items to compensate for technical debt or UI concerns such as\nReactJS preferences for having ids within arrays if the data is not modeled that way.\n\nIf you add a new transform of the output called \"myNewTransform\" do it\nin the form of:\nflow(removeIdFromExceptionItemsEntries, myNewTransform)(exceptionItem)\n" ], "signature": [ - "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" + "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -234,7 +234,7 @@ "The exceptionItem to transform the output of" ], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -407,7 +407,7 @@ "section": "def-common.DeleteListParams", "text": "DeleteListParams" }, - ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" + ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_delete_list/index.ts", "deprecated": false, @@ -545,7 +545,7 @@ "section": "def-common.FindListsParams", "text": "FindListsParams" }, - ">], { cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" + ">], { cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_find_lists/index.ts", "deprecated": false, @@ -586,7 +586,7 @@ "section": "def-common.FindListsParams", "text": "FindListsParams" }, - ">], { largeLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; smallLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; }>" + ">], { largeLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; smallLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_find_lists_by_size/index.ts", "deprecated": false, @@ -627,7 +627,7 @@ "section": "def-common.ImportListParams", "text": "ImportListParams" }, - ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" + ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_import_list/index.ts", "deprecated": false, @@ -851,7 +851,7 @@ "label": "addExceptionListItem", "description": [], "signature": [ - "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -876,7 +876,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -895,7 +895,7 @@ "label": "updateExceptionListItem", "description": [], "signature": [ - "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -920,7 +920,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -1039,7 +1039,7 @@ "section": "def-common.ApiCallMemoProps", "text": "ApiCallMemoProps" }, - " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }) => Promise" + " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }) => Promise" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -1060,7 +1060,7 @@ "section": "def-common.ApiCallMemoProps", "text": "ApiCallMemoProps" }, - " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }" + " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -1423,7 +1423,7 @@ "label": "ReturnPersistExceptionItem", "description": [], "signature": [ - "[PersistReturnExceptionItem, React.Dispatch<({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | null>]" + "[PersistReturnExceptionItem, React.Dispatch<({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | null>]" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_persist_exception_item/index.ts", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index 6b6df40fb4339..ea0c67170bcac 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.devdocs.json b/api_docs/kbn_securitysolution_list_utils.devdocs.json index e874763d9e630..4fe323489c217 100644 --- a/api_docs/kbn_securitysolution_list_utils.devdocs.json +++ b/api_docs/kbn_securitysolution_list_utils.devdocs.json @@ -27,7 +27,7 @@ "label": "addIdToEntries", "description": [], "signature": [ - "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -41,7 +41,7 @@ "label": "entries", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -314,7 +314,7 @@ "section": "def-common.FormattedBuilderEntry", "text": "FormattedBuilderEntry" }, - ") => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }" + ") => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -474,7 +474,7 @@ "section": "def-common.FormattedBuilderEntry", "text": "FormattedBuilderEntry" }, - ", newField: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }) => { index: number; updatedEntry: ", + ", newField: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }) => { index: number; updatedEntry: ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -521,7 +521,7 @@ "- newly selected list" ], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -2108,7 +2108,7 @@ "label": "hasLargeValueList", "description": [], "signature": [ - "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => boolean" + "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => boolean" ], "path": "packages/kbn-securitysolution-list-utils/src/has_large_value_list/index.ts", "deprecated": false, @@ -2122,7 +2122,7 @@ "label": "entries", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-list-utils/src/has_large_value_list/index.ts", "deprecated": false, @@ -2779,7 +2779,7 @@ "label": "BuilderEntry", "description": [], "signature": [ - "(({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }) | ", + "(({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }) | ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -2840,7 +2840,7 @@ "label": "CreateExceptionListItemBuilderSchema", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"entries\" | \"meta\" | \"list_id\" | \"namespace_type\"> & { meta: { temporaryUuid: string; }; entries: ", + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"entries\" | \"meta\" | \"list_id\" | \"namespace_type\"> & { meta: { temporaryUuid: string; }; entries: ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -2966,7 +2966,7 @@ "label": "ExceptionListItemBuilderSchema", "description": [], "signature": [ - "Omit<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }, \"entries\"> & { entries: ", + "Omit<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }, \"entries\"> & { entries: ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -3033,7 +3033,7 @@ "label": "ExceptionsBuilderReturnExceptionItem", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; list_id?: undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; list_id?: undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" ], "path": "packages/kbn-securitysolution-list-utils/src/types/index.ts", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index ec4fad69827a7..134ca5e360ca2 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index 43e6570937494..335f4c299ed73 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index 57ae0b6f18b6e..9705017577793 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index 188204ced4469..b0fadb56e32ca 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index b6b8344020a4b..4c0b45c1273cb 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index b18e9eb7920f5..52283100abbc1 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index 011737b9c6f7c..316e48226bae7 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_solution.mdx b/api_docs/kbn_shared_ux_avatar_solution.mdx index 9586ca5d21670..e769b5a784e2f 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index 1980f15830804..05d911c2a5c82 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index f90b3abd952be..e51317e0af2bd 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index e8934021f37b3..9c6ce26ba3ee6 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 122f0fc6bf596..cba1def03b762 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index 8b7374aa372d5..dd67a2c134ddf 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index 5219eb7e424c9..25568d770ba06 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index d5f96ff9fd694..fe2a2675c45f6 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-context'] --- import kbnSharedUxFileContextObj from './kbn_shared_ux_file_context.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image.mdx b/api_docs/kbn_shared_ux_file_image.mdx index 0c3cacfbf1e60..80d0d0760af51 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image'] --- import kbnSharedUxFileImageObj from './kbn_shared_ux_file_image.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image_mocks.mdx b/api_docs/kbn_shared_ux_file_image_mocks.mdx index 07a09baf66def..448e155417e08 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image-mocks'] --- import kbnSharedUxFileImageMocksObj from './kbn_shared_ux_file_image_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_mocks.mdx b/api_docs/kbn_shared_ux_file_mocks.mdx index 011d08457143e..0b927ab8079f6 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-mocks'] --- import kbnSharedUxFileMocksObj from './kbn_shared_ux_file_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_picker.mdx b/api_docs/kbn_shared_ux_file_picker.mdx index 67c3b087824e7..163bdbd1316cb 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-picker'] --- import kbnSharedUxFilePickerObj from './kbn_shared_ux_file_picker.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_upload.mdx b/api_docs/kbn_shared_ux_file_upload.mdx index 5c553db61b198..3e87e8bdaa72c 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-upload'] --- import kbnSharedUxFileUploadObj from './kbn_shared_ux_file_upload.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_util.mdx b/api_docs/kbn_shared_ux_file_util.mdx index 2905182ef04e7..c424d8e88aac7 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-util'] --- import kbnSharedUxFileUtilObj from './kbn_shared_ux_file_util.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app.mdx b/api_docs/kbn_shared_ux_link_redirect_app.mdx index f6639024d53f5..e8213f3111c53 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app'] --- import kbnSharedUxLinkRedirectAppObj from './kbn_shared_ux_link_redirect_app.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index 9b29f7b4976d2..f04c04386b696 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown.mdx b/api_docs/kbn_shared_ux_markdown.mdx index 705ba8ecabfdb..825a52f29d24b 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown'] --- import kbnSharedUxMarkdownObj from './kbn_shared_ux_markdown.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown_mocks.mdx b/api_docs/kbn_shared_ux_markdown_mocks.mdx index 6e7a5deea786c..dcd2e7576b973 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown-mocks'] --- import kbnSharedUxMarkdownMocksObj from './kbn_shared_ux_markdown_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index 20b0d03aee1f5..1ea1769844301 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index 2220f77020d53..d4344a2edb7d0 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index d569b8cb3c8e8..9a23865a9d39b 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index d19566f2ef7e4..c542f315b5dd1 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx index e18fa11132dd8..78bddfa5de403 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] --- import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx index e8b77b2a71e84..8192dff2449f8 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] --- import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx index 2a42cf7e02774..e2f62a7e69593 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx index 5510537e1494d..43723d1181d01 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx index dc252ddb19924..5b7bf8f6c12ec 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] --- import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx index c856ab3c0ff1f..afc6bd84f32d0 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] --- import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index a906643048766..edd0ad93ed24f 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index 8b6c3d95db0f4..241cc809bdaad 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index 9258921eaefb4..e462f2c0e5c65 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_not_found.mdx b/api_docs/kbn_shared_ux_prompt_not_found.mdx index dd5f00ef3e2d0..dffe5c2247f2d 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-not-found'] --- import kbnSharedUxPromptNotFoundObj from './kbn_shared_ux_prompt_not_found.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router.mdx b/api_docs/kbn_shared_ux_router.mdx index 3f9eca1f65810..870fed94d8383 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router'] --- import kbnSharedUxRouterObj from './kbn_shared_ux_router.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router_mocks.mdx b/api_docs/kbn_shared_ux_router_mocks.mdx index a8725541e9c1a..d8f97d5f50ac9 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router-mocks'] --- import kbnSharedUxRouterMocksObj from './kbn_shared_ux_router_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_config.mdx b/api_docs/kbn_shared_ux_storybook_config.mdx index 7a212d229cb9e..a030330082563 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-config'] --- import kbnSharedUxStorybookConfigObj from './kbn_shared_ux_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index 39f093bccd2dc..acb61141fa566 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index a3702e18e22bc..4d4c9731702ff 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_slo_schema.mdx b/api_docs/kbn_slo_schema.mdx index 24034136145ea..6a1332238b333 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/slo-schema'] --- import kbnSloSchemaObj from './kbn_slo_schema.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index 8ecc8fe3a408e..8bf96726acc57 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 323dbe09b28b7..c885fb60b7ff4 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index d9ed8f99f1ac3..3af966a999afe 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index 9d7315513e9c5..ba2cf954dbdb6 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 2f48f1ebdc71b..0f53d02b03fae 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index e1ca177807117..29520c4dadab9 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index ef39a9ec62e79..68d4aeafb3ed7 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index bea74b9e4521a..ffbbb0c11f951 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 4100c5dfc4653..7a53910e3f226 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 4ecf653c3a8e6..72d6261c0bd75 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ts-projects'] --- import kbnTsProjectsObj from './kbn_ts_projects.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index 039d0b773ba04..f0148700e75fc 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 24a10f326fea9..3930200545780 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-shared-deps-src'] --- import kbnUiSharedDepsSrcObj from './kbn_ui_shared_deps_src.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index b4df2b35fac15..b17aa744d4f70 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 36edcef41a27b..173892aef0a28 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index 3e7d2a8924a83..4ac2d5a90fac2 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index 4663b6cc7ce18..ce31e7f13af76 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index 16177cc0e976e..d3f3d2c20b5ce 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 495a8fd07732b..c7f372d17ce13 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 1f442d2c75083..ccc49b2480e41 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index aaadb1122a262..f863adfa011db 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index dcda5c4327545..291b321834040 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index 78c83bf590a42..486b7e288918d 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 9c339b2cbc3a7..8bea4499a7bdd 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 67d1d16d1dc93..12ac8378f21ef 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index 620542f15be69..392be28b9a38a 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index bf25d392cbe29..051d8a6071cb1 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.devdocs.json b/api_docs/lists.devdocs.json index 6233f803836c3..711eb0bcf6a20 100644 --- a/api_docs/lists.devdocs.json +++ b/api_docs/lists.devdocs.json @@ -345,7 +345,7 @@ "label": "exceptionsToDelete", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" ], "path": "x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx", "deprecated": false, @@ -622,7 +622,7 @@ "signature": [ "({ itemId, id, namespaceType, }: ", "GetExceptionListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -700,7 +700,7 @@ "signature": [ "({ comments, description, entries, itemId, meta, name, osTypes, tags, type, }: ", "CreateEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -776,7 +776,7 @@ "signature": [ "({ _version, comments, description, entries, id, itemId, meta, name, osTypes, tags, type, }: ", "UpdateEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -814,7 +814,7 @@ "signature": [ "({ itemId, id, }: ", "GetEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -972,7 +972,7 @@ "section": "def-server.CreateExceptionListItemOptions", "text": "CreateExceptionListItemOptions" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1022,7 +1022,7 @@ "section": "def-server.UpdateExceptionListItemOptions", "text": "UpdateExceptionListItemOptions" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1066,7 +1066,7 @@ "signature": [ "({ id, itemId, namespaceType, }: ", "DeleteExceptionListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1140,7 +1140,7 @@ "signature": [ "({ id, itemId, }: ", "DeleteEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1176,7 +1176,7 @@ "signature": [ "({ listId, filter, perPage, pit, page, search, searchAfter, sortField, sortOrder, namespaceType, }: ", "FindExceptionListItemOptions", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1214,7 +1214,7 @@ "signature": [ "({ listId, filter, perPage, pit, page, search, searchAfter, sortField, sortOrder, namespaceType, }: ", "FindExceptionListsItemOptions", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1252,7 +1252,7 @@ "signature": [ "({ perPage, pit, page, searchAfter, sortField, sortOrder, valueListId, }: ", "FindValueListExceptionListsItems", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1328,7 +1328,7 @@ "signature": [ "({ filter, perPage, page, pit, search, searchAfter, sortField, sortOrder, }: ", "FindEndpointListItemOptions", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1814,7 +1814,7 @@ "signature": [ "({ id }: ", "GetListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1852,7 +1852,7 @@ "signature": [ "({ id, deserializer, immutable, serializer, name, description, type, meta, version, }: ", "CreateListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1890,7 +1890,7 @@ "signature": [ "({ id, deserializer, serializer, name, description, immutable, type, meta, version, }: ", "CreateListIfItDoesNotExistOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2408,7 +2408,7 @@ "signature": [ "({ id }: ", "DeleteListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2446,7 +2446,7 @@ "signature": [ "({ listId, value, type, }: ", "DeleteListItemByValueOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2484,7 +2484,7 @@ "signature": [ "({ id }: ", "DeleteListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2558,7 +2558,7 @@ "signature": [ "({ deserializer, serializer, type, listId, stream, meta, version, }: ", "ImportListItemsToStreamOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2594,7 +2594,7 @@ "signature": [ "({ listId, value, type, }: ", "GetListItemByValueOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2632,7 +2632,7 @@ "signature": [ "({ id, deserializer, serializer, listId, value, type, meta, }: ", "CreateListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2668,7 +2668,7 @@ "signature": [ "({ _version, id, value, meta, }: ", "UpdateListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2704,7 +2704,7 @@ "signature": [ "({ _version, id, name, description, meta, version, }: ", "UpdateListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2740,7 +2740,7 @@ "signature": [ "({ id }: ", "GetListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2778,7 +2778,7 @@ "signature": [ "({ type, listId, value, }: ", "GetListItemsByValueOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2816,7 +2816,7 @@ "signature": [ "({ type, listId, value, }: ", "SearchListItemByValuesOptions", - ") => Promise<{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]>" + ") => Promise<{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2854,7 +2854,7 @@ "signature": [ "({ filter, currentIndexPosition, perPage, page, sortField, sortOrder, searchAfter, runtimeMappings, }: ", "FindListOptions", - ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" + ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2892,7 +2892,7 @@ "signature": [ "({ listId, filter, currentIndexPosition, perPage, page, runtimeMappings, sortField, sortOrder, searchAfter, }: ", "FindListItemOptions", - ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; } | null>" + ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2928,7 +2928,7 @@ "signature": [ "({ listId, filter, sortField, sortOrder, }: ", "FindAllListItemsOptions", - ") => Promise<{ data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; total: number; } | null>" + ") => Promise<{ data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; total: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2997,7 +2997,7 @@ "an array with the exception list item entries" ], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts", "deprecated": false, @@ -3309,7 +3309,7 @@ "item exception entries logic" ], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts", "deprecated": false, diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index bd9501f4bb7c4..5f8da7a5e33dc 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 547de58186cf6..cd268de888f6e 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index c2bc9c07438b6..5c101eac778a5 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index b3a7fff40a34f..3a074b874b3e3 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 980edf782929a..f1564fbfc1326 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 683de42a7d0eb..52550cadc48a6 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index afeb74fa1fc45..00b3f061260e8 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index 036dd75f06505..e3742c0fbb812 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 3ee76d079e2c9..21d8c6e411a04 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index f57b1ca9bbeb4..d47d889932b31 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index 0c0fd503e0ebf..f99c1d1c40cd7 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index bd1d66b00d72a..bc09040011453 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index a6689eb63f227..2e29dcfb005a0 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 34363 | 526 | 24007 | 1191 | +| 34421 | 526 | 24056 | 1196 | ## Plugin Directory @@ -30,8 +30,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 220 | 8 | 215 | 24 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 36 | 1 | 32 | 2 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 12 | 0 | 1 | 2 | -| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 434 | 0 | 425 | 37 | -| | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 42 | 0 | 42 | 59 | +| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 465 | 0 | 456 | 38 | +| | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 42 | 0 | 42 | 61 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 9 | 0 | 9 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Considering using bfetch capabilities when fetching large amounts of data. This services supports batching HTTP requests and streaming responses back. | 89 | 1 | 74 | 2 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Canvas application to Kibana | 9 | 0 | 8 | 3 | @@ -84,7 +84,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-visualizations) | Expression Tagcloud plugin adds a `tagcloud` renderer and function to the expression plugin. The renderer will display the `Wordcloud` chart. | 7 | 0 | 7 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-visualizations) | Expression XY plugin adds a `xy` renderer and function to the expression plugin. The renderer will display the `xy` chart. | 170 | 0 | 160 | 13 | | | [Visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Adds expression runtime to Kibana | 2205 | 74 | 1746 | 5 | -| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 227 | 0 | 96 | 2 | +| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 236 | 0 | 100 | 2 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Index pattern fields and ambiguous values formatters | 288 | 26 | 249 | 3 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 62 | 0 | 62 | 2 | | | [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/team:AppServicesUx) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 254 | 1 | 45 | 5 | @@ -145,7 +145,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Kibana Screenshotting Plugin | 27 | 0 | 8 | 4 | | searchprofiler | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 269 | 0 | 89 | 0 | -| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 113 | 0 | 76 | 29 | +| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 115 | 0 | 75 | 29 | | | [Security Team](https://github.com/orgs/elastic/teams/security-team) | - | 7 | 0 | 7 | 1 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds URL Service and sharing capabilities to Kibana | 115 | 0 | 56 | 10 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 22 | 1 | 22 | 1 | @@ -158,7 +158,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 31 | 0 | 26 | 6 | | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 1 | 0 | 1 | 0 | | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 5 | 0 | 0 | 0 | -| | [Protections Experience Team](https://github.com/orgs/elastic/teams/protections-experience) | Elastic threat intelligence helps you see if you are open to or have been subject to current or historical known threats | 34 | 0 | 14 | 3 | +| | [Protections Experience Team](https://github.com/orgs/elastic/teams/protections-experience) | Elastic threat intelligence helps you see if you are open to or have been subject to current or historical known threats | 35 | 0 | 15 | 5 | | | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 257 | 1 | 214 | 21 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the transforms features provided by Elastic. Transforms enable you to convert existing Elasticsearch indices into summarized indices, which provide opportunities for new insights and analytics. | 4 | 0 | 4 | 1 | | translations | [Kibana Localization](https://github.com/orgs/elastic/teams/kibana-localization) | - | 0 | 0 | 0 | 0 | @@ -209,7 +209,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Owner missing] | Elastic APM trace data generator | 152 | 0 | 152 | 16 | | | [Owner missing] | - | 11 | 0 | 11 | 0 | | | [Owner missing] | - | 10 | 0 | 10 | 0 | -| | [Owner missing] | - | 4 | 0 | 3 | 0 | +| | [Owner missing] | - | 19 | 0 | 17 | 0 | | | [Owner missing] | - | 76 | 0 | 76 | 0 | | | [Owner missing] | - | 7 | 0 | 2 | 0 | | | [Owner missing] | - | 3 | 0 | 3 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index f07dc1d0827f2..ddd22b5d98288 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index ed67b9bccaf19..8462ab9eb55fb 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index 70d556a68e7bd..88dace58a3c61 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index 109af07f830cb..ef66af531507a 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 677a476c05509..26f6e01cca7c9 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index 9f1d7e5f473c1..df05b55ca5667 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index b5f71065e2d87..914f9ac25522e 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index 169950252ec53..929a546f33117 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index fe63bddaa2bc4..4166448900097 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index 571fdaaddd420..b653be79e3633 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 0f422a9cce513..a96a6a681bea3 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index b4492f7587997..809da024dc792 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index b00801737aacf..8d937b0d75f65 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index 21cc587186a52..28d5b1ec1cc5e 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index 49914ef86e4c4..d619dde786e52 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 517dfef448cd0..d383f6e06ffc1 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 3dd7644fcda20..e70de928b1689 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 6218cc41e50ae..08e18cd79b9a7 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index 53d83173466af..db3279168e6de 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 859dde812cdf3..aa246037a4cf6 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index 8956320d61ef0..106ebabcc4c1d 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index 9b84abb991b38..61cc97e81204d 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/stack_connectors.mdx b/api_docs/stack_connectors.mdx index 624e9006fcf29..73dab132ff84e 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index 02838c30dfd53..cfa406bccfe48 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index 21fa66fe06ac9..1d8f1d3df1f0b 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index 2e51147df7aa9..0a1f7b7fdcb76 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index 6938c7fd8cade..d86369dfe67b3 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 9bf4c7f33cc1b..763979a5eff90 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/threat_intelligence.devdocs.json b/api_docs/threat_intelligence.devdocs.json index bf7f44448dd5f..ccce9277fb240 100644 --- a/api_docs/threat_intelligence.devdocs.json +++ b/api_docs/threat_intelligence.devdocs.json @@ -502,6 +502,24 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "threatIntelligence", + "id": "def-public.SecuritySolutionPluginContext.blockList", + "type": "Object", + "tags": [], + "label": "blockList", + "description": [], + "signature": [ + "{ exceptionListApiClient: unknown; useSetUrlParams: () => (params: Record, replace?: boolean | undefined) => void; getFlyoutComponent: () => React.NamedExoticComponent<", + "BlockListFlyoutProps", + ">; getFormComponent: () => React.NamedExoticComponent<", + "BlockListFormProps", + ">; }" + ], + "path": "x-pack/plugins/threat_intelligence/public/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 8736f109defdb..24658e3241a42 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Protections Experience Team](https://github.com/orgs/elastic/teams/prot | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 34 | 0 | 14 | 3 | +| 35 | 0 | 15 | 5 | ## Client diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index ca0ab19f125b2..ea2a77e7bfbc2 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index 141ed80e1f5bb..15e4275f94f50 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index 8a70841d05442..a436aa93a9e9f 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 258a42d01b927..34657422ae5e7 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index cff921baf8f1d..5a81db30bd685 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_field_list.mdx b/api_docs/unified_field_list.mdx index 386fae3b78e90..d57456df72039 100644 --- a/api_docs/unified_field_list.mdx +++ b/api_docs/unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedFieldList title: "unifiedFieldList" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedFieldList plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedFieldList'] --- import unifiedFieldListObj from './unified_field_list.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index fb79fdad9d39e..f2ea75c43ffd7 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index 1d51a3363b843..35af51292c3cd 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 22ef0c99064dd..53a1e31d8b329 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index c16abcb49f2e1..d5094c9442c1d 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index eca30327b33a3..9be1a43cb976a 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index 3336cb7a766fb..56b138bd99d8e 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index 9b140bdafe129..3015962d01757 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index 6064bda171133..d7a967f6d0e58 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index 64a1164f4ce1e..9afe90971c5c5 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index 07e40e1c6f8f4..7db8de3127c0a 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index 89709935d4732..93af1b9bf0586 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index 05524083548c4..3f41d9c61c500 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index 8aa22f534bda4..db0179826dda0 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index feeb00870e051..81816a86889a3 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 6ba6de1bec540..ac72c300fb600 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index b15b0c4cf2a7b..61698abcaacb3 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2023-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index abb23a698980f..6ccc21fc6c089 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-01-17 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From eb8aab093a2b80d25432b310e73ad2800f4dafb2 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 18 Jan 2023 09:03:13 +0200 Subject: [PATCH 23/44] [Unified search] Fix the bug with the default value on numeric field filters (#149028) ## Summary Closes https://github.com/elastic/kibana/issues/149020 I created this bad ux with https://github.com/elastic/kibana/pull/148802 When you try to add a negative value to a numeric field filter, is not easily applied. I changed the behavior, so now the 0 is not automatically added on the operator selection, the user can still add a filter without a required value and I fixed the preview. image --- .../src/filters/helpers/update_filter.test.ts | 2 +- .../src/filters/helpers/update_filter.ts | 2 +- .../lib/get_display_value.test.ts | 27 +++++++++++++++++++ .../filter_manager/lib/get_display_value.ts | 4 ++- .../filter_manager/lib/mappers/map_phrase.ts | 8 +++--- 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/packages/kbn-es-query/src/filters/helpers/update_filter.test.ts b/packages/kbn-es-query/src/filters/helpers/update_filter.test.ts index b57855bf472e8..7c33cf36e07c0 100644 --- a/packages/kbn-es-query/src/filters/helpers/update_filter.test.ts +++ b/packages/kbn-es-query/src/filters/helpers/update_filter.test.ts @@ -127,7 +127,7 @@ describe('updateFilter', () => { meta: { alias: '', index: 'index1', - params: { query: 0 }, + params: { query: undefined }, key: 'test-field', negate: true, type: 'phrase', diff --git a/packages/kbn-es-query/src/filters/helpers/update_filter.ts b/packages/kbn-es-query/src/filters/helpers/update_filter.ts index 1ebe43cbdbfd0..ea61545d557be 100644 --- a/packages/kbn-es-query/src/filters/helpers/update_filter.ts +++ b/packages/kbn-es-query/src/filters/helpers/update_filter.ts @@ -79,7 +79,7 @@ function updateWithIsOperator( ...filter.meta, negate: operator?.negate, type: operator?.type, - params: { ...filter.meta.params, query: safeParams }, + params: { ...filter.meta.params, query: params }, value: undefined, }, query: { match_phrase: { [filter.meta.key!]: safeParams ?? '' } }, diff --git a/src/plugins/data/public/query/filter_manager/lib/get_display_value.test.ts b/src/plugins/data/public/query/filter_manager/lib/get_display_value.test.ts index d32323d4d0b23..455e01663acae 100644 --- a/src/plugins/data/public/query/filter_manager/lib/get_display_value.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/get_display_value.test.ts @@ -36,6 +36,33 @@ describe('getDisplayValueFromFilter', () => { expect(displayValue).toBe(''); }); + it('returns 0 if value undefined and numeric field', () => { + const filter = { + meta: { + negate: false, + index: 'logstash-*', + type: 'phrase', + key: 'bytes', + value: undefined, + disabled: false, + alias: null, + params: { + query: undefined, + }, + }, + $state: { + store: FilterStateStore.APP_STATE, + }, + query: { + match_phrase: { + bytes: '0', + }, + }, + }; + const displayValue = getDisplayValueFromFilter(filter, [stubIndexPattern]); + expect(displayValue).toBe('0'); + }); + it('phrase filters without formatter', () => { jest.spyOn(stubIndexPattern, 'getFormatterForField').mockImplementation(() => undefined!); const displayValue = getDisplayValueFromFilter(phraseFilter, [stubIndexPattern]); diff --git a/src/plugins/data/public/query/filter_manager/lib/get_display_value.ts b/src/plugins/data/public/query/filter_manager/lib/get_display_value.ts index 6a8f5d895728a..bb1d6a464cb04 100644 --- a/src/plugins/data/public/query/filter_manager/lib/get_display_value.ts +++ b/src/plugins/data/public/query/filter_manager/lib/get_display_value.ts @@ -61,10 +61,12 @@ export function getFieldDisplayValueFromFilter( export function getDisplayValueFromFilter(filter: Filter, indexPatterns: DataViewBase[]): string { const indexPattern = getIndexPatternFromFilter(filter, indexPatterns); const fieldName = getFilterField(filter); + const field = indexPattern?.fields.find((f) => f.name === fieldName); + const fieldType = field?.type; const valueFormatter = getValueFormatter(indexPattern, fieldName); if (isPhraseFilter(filter) || isScriptedPhraseFilter(filter)) { - return getPhraseDisplayValue(filter, valueFormatter); + return getPhraseDisplayValue(filter, valueFormatter, fieldType); } else if (isPhrasesFilter(filter)) { return getPhrasesDisplayValue(filter, valueFormatter); } else if (isRangeFilter(filter) || isScriptedRangeFilter(filter)) { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts index 3bbe9b886cf6a..6058a125c9a54 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts @@ -22,13 +22,15 @@ const getScriptedPhraseValue = (filter: PhraseFilter) => export function getPhraseDisplayValue( filter: PhraseFilter | ScriptedPhraseFilter, - formatter?: FieldFormat + formatter?: FieldFormat, + fieldType?: string ): string { const value = filter.meta.value ?? filter.meta.params.query; + const updatedValue = fieldType === 'number' && !value ? 0 : value; if (formatter?.convert) { - return formatter.convert(value); + return formatter.convert(updatedValue); } - return value === undefined ? '' : `${value}`; + return updatedValue === undefined ? '' : `${updatedValue}`; } const getParams = (filter: PhraseFilter) => { From 723fb386286725e67a9d8e037108b67ba818e204 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Wed, 18 Jan 2023 03:02:57 -0500 Subject: [PATCH 24/44] [Synthetics] monitor details - use configId for locations in monitor details card (#149085) Resolves https://github.com/elastic/kibana/issues/149084 --- .../components/common/components/monitor_details_panel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_details_panel.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_details_panel.tsx index 66d4f99b4bae2..901dbf21b2d90 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_details_panel.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_details_panel.tsx @@ -123,7 +123,7 @@ export const MonitorDetailsPanel = ({ {frequencyStr(monitor[ConfigKey.SCHEDULE])} {LOCATIONS_LABEL} - + {TAGS_LABEL} From 5d6d5bb58bd0007571e2fb56eeb3286256f40a78 Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Wed, 18 Jan 2023 09:48:07 +0100 Subject: [PATCH 25/44] [AO] Add functional test for Alert Summary Widget on Rule Details page (#148744) Closes #148536 ## Summary Add functional test for Alert Summary Widget on Rule Details page. Flaky test runner[100]: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/1735 --- .../components/alert_state_info.tsx | 2 +- .../alert_summary_widget_compact.tsx | 6 ++- .../components/alert_search_bar.ts | 38 ++++++++++++++++ .../components/alert_summary_widget.ts | 40 +++++++++++++++++ .../observability/components/index.ts | 21 +++++++++ .../services/observability/index.ts | 3 ++ .../observability_security.ts | 5 +++ .../observability/pages/rule_details_page.ts | 43 +++++++++++++++++++ 8 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 x-pack/test/functional/services/observability/components/alert_search_bar.ts create mode 100644 x-pack/test/functional/services/observability/components/alert_summary_widget.ts create mode 100644 x-pack/test/functional/services/observability/components/index.ts diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/components/alert_state_info.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/components/alert_state_info.tsx index 84db4ed4a78cb..01e3aff049d3e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/components/alert_state_info.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/components/alert_state_info.tsx @@ -62,7 +62,7 @@ export const AlertStateInfo = ({ -

    {count}

    +

    {count}

    {title} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/components/alert_summary_widget_compact.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/components/alert_summary_widget_compact.tsx index 341d87b5162af..fd77161361dab 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/components/alert_summary_widget_compact.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/components/alert_summary_widget_compact.tsx @@ -88,11 +88,12 @@ export const AlertsSummaryWidgetCompact = ({ onClick={(event: React.MouseEvent) => handleClick(event, ALERT_STATUS_ACTIVE) } + data-test-subj="activeAlerts" > ) => handleClick(event, ALERT_STATUS_RECOVERED) } + data-test-subj="recoveredAlerts" > { + // Since FTR uses UTC, with this format, we remove local browser timezone + const format = 'YYYY-MM-DDTHH:mm:ss.SSS'; + + const fromMoment = dateMath.parse( + await (await testSubjects.find(FROM_SELECTOR)).getVisibleText() + ); + const from = fromMoment!.format(format); + + const toMoment = dateMath.parse(await (await testSubjects.find(TO_SELECTOR)).getVisibleText()); + const to = toMoment!.format(format); + + return { + from, + to, + }; + }; + + return { + getAbsoluteTimeRange, + }; +} diff --git a/x-pack/test/functional/services/observability/components/alert_summary_widget.ts b/x-pack/test/functional/services/observability/components/alert_summary_widget.ts new file mode 100644 index 0000000000000..1d486a497c735 --- /dev/null +++ b/x-pack/test/functional/services/observability/components/alert_summary_widget.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../../ftr_provider_context'; + +const COMPACT_COMPONENT_SELECTOR = 'alertSummaryWidgetCompact'; +const COMPACT_TIME_RANGE_TITLE_SELECTOR = 'timeRangeTitle'; +const COMPACT_ACTIVE_ALERTS_SELECTOR = 'activeAlerts'; +const COMPACT_RECOVERED_ALERTS_SELECTOR = 'recoveredAlerts'; + +export function ObservabilityAlertSummaryWidgetProvider({ getService }: FtrProviderContext) { + const testSubjects = getService('testSubjects'); + + const getCompactComponentSelectorOrFail = async () => { + return await testSubjects.existOrFail(COMPACT_COMPONENT_SELECTOR); + }; + + const getCompactTimeRangeTitle = async () => { + return (await testSubjects.find(COMPACT_TIME_RANGE_TITLE_SELECTOR)).getVisibleText(); + }; + + const getCompactActiveAlertSelector = async () => { + return await testSubjects.find(COMPACT_ACTIVE_ALERTS_SELECTOR); + }; + + const getCompactRecoveredAlertSelector = async () => { + return await testSubjects.find(COMPACT_RECOVERED_ALERTS_SELECTOR); + }; + + return { + getCompactComponentSelectorOrFail, + getCompactTimeRangeTitle, + getCompactActiveAlertSelector, + getCompactRecoveredAlertSelector, + }; +} diff --git a/x-pack/test/functional/services/observability/components/index.ts b/x-pack/test/functional/services/observability/components/index.ts new file mode 100644 index 0000000000000..0a11968a0cb56 --- /dev/null +++ b/x-pack/test/functional/services/observability/components/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. + */ + +import { ObservabilityAlertSearchBarProvider } from './alert_search_bar'; +import { ObservabilityAlertSummaryWidgetProvider } from './alert_summary_widget'; + +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export function ObservabilityComponentsProvider(context: FtrProviderContext) { + const alertSearchBar = ObservabilityAlertSearchBarProvider(context); + const alertSummaryWidget = ObservabilityAlertSummaryWidgetProvider(context); + + return { + alertSearchBar, + alertSummaryWidget, + }; +} diff --git a/x-pack/test/functional/services/observability/index.ts b/x-pack/test/functional/services/observability/index.ts index 2b2c82c4f3728..db262cef8bf63 100644 --- a/x-pack/test/functional/services/observability/index.ts +++ b/x-pack/test/functional/services/observability/index.ts @@ -9,14 +9,17 @@ import { FtrProviderContext } from '../../ftr_provider_context'; import { ObservabilityUsersProvider } from './users'; import { ObservabilityAlertsProvider } from './alerts'; import { ObservabilityOverviewProvider } from './overview'; +import { ObservabilityComponentsProvider } from './components'; export function ObservabilityProvider(context: FtrProviderContext) { const alerts = ObservabilityAlertsProvider(context); + const components = ObservabilityComponentsProvider(context); const users = ObservabilityUsersProvider(context); const overview = ObservabilityOverviewProvider(context); return { alerts, + components, users, overview, }; diff --git a/x-pack/test/observability_functional/apps/observability/feature_controls/observability_security.ts b/x-pack/test/observability_functional/apps/observability/feature_controls/observability_security.ts index 85512f8333038..436dcad75f305 100644 --- a/x-pack/test/observability_functional/apps/observability/feature_controls/observability_security.ts +++ b/x-pack/test/observability_functional/apps/observability/feature_controls/observability_security.ts @@ -20,6 +20,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { ]); const appsMenu = getService('appsMenu'); const testSubjects = getService('testSubjects'); + const config = getService('config'); + const kibanaServer = getService('kibanaServer'); describe('observability security feature controls', function () { this.tags(['skipFirefox']); @@ -29,6 +31,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { after(async () => { await esArchiver.unload('x-pack/test/functional/es_archives/cases/default'); + // Since the above unload removes the default config, + // the following command will set it back to avoid changing the test environment + await kibanaServer.uiSettings.update(config.get('uiSettings.defaults')); }); it('Shows the no data page on load', async () => { diff --git a/x-pack/test/observability_functional/apps/observability/pages/rule_details_page.ts b/x-pack/test/observability_functional/apps/observability/pages/rule_details_page.ts index 6ab449873fc76..1447375c5745b 100644 --- a/x-pack/test/observability_functional/apps/observability/pages/rule_details_page.ts +++ b/x-pack/test/observability_functional/apps/observability/pages/rule_details_page.ts @@ -16,6 +16,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; export default ({ getService }: FtrProviderContext) => { const testSubjects = getService('testSubjects'); + const browser = getService('browser'); const observability = getService('observability'); const supertest = getService('supertest'); const find = getService('find'); @@ -141,6 +142,48 @@ export default ({ getService }: FtrProviderContext) => { }); }); + describe('Alert summary widget component', () => { + before(async () => { + await observability.alerts.common.navigateToRuleDetailsByRuleId(uptimeRuleId); + }); + + it('shows component on the rule detils page', async () => { + await observability.components.alertSummaryWidget.getCompactComponentSelectorOrFail(); + + const timeRangeTitle = + await observability.components.alertSummaryWidget.getCompactTimeRangeTitle(); + expect(timeRangeTitle).to.be('Last 30 days'); + }); + + it('handles clicking on active correctly', async () => { + const activeAlerts = + await observability.components.alertSummaryWidget.getCompactActiveAlertSelector(); + await activeAlerts.click(); + + const url = await browser.getCurrentUrl(); + const { from, to } = await observability.components.alertSearchBar.getAbsoluteTimeRange(); + + expect(url.includes('tabId=alerts')).to.be(true); + expect(url.includes('status%3Aactive')).to.be(true); + expect(url.includes(from.replaceAll(':', '%3A'))).to.be(true); + expect(url.includes(to.replaceAll(':', '%3A'))).to.be(true); + }); + + it('handles clicking on recovered correctly', async () => { + const recoveredAlerts = + await observability.components.alertSummaryWidget.getCompactRecoveredAlertSelector(); + await recoveredAlerts.click(); + + const url = await browser.getCurrentUrl(); + const { from, to } = await observability.components.alertSearchBar.getAbsoluteTimeRange(); + + expect(url.includes('tabId=alerts')).to.be(true); + expect(url.includes('status%3Arecovered')).to.be(true); + expect(url.includes(from.replaceAll(':', '%3A'))).to.be(true); + expect(url.includes(to.replaceAll(':', '%3A'))).to.be(true); + }); + }); + describe('User permissions', () => { before(async () => { await observability.alerts.common.navigateToRuleDetailsByRuleId(logThresholdRuleId); From 26d0cc8ff0464aba93db9560e07aed2fd687f9cd Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Wed, 18 Jan 2023 09:49:52 +0100 Subject: [PATCH 26/44] [AO] Fix failed functional test - Observability alerts Alerts table Flyout Can be closed (#148882) Closes #145835 ## Summary Fix `Observability alerts Alerts table Flyout Can be closed` by retrying closing flyout if it is still open. This issue happens rarely (only once in the main and 3 times in other branches during the last 3 months - [link](https://ops.kibana.dev/s/ci/app/dashboards#/view/cb7380fb-67fe-5c41-873d-003d1a407dad?_g=(filters:!(('$state':(store:globalState),meta:(alias:!n,disabled:!f,index:'1f96f3c7-e086-5f46-a8e0-40d2b811928c',key:failure.name,negate:!f,params:(query:'ObservabilityApp%20Observability%20alerts%20Alerts%20table%20Flyout%20Can%20be%20closed'),type:phrase),query:(match_phrase:(failure.name:'ObservabilityApp%20Observability%20alerts%20Alerts%20table%20Flyout%20Can%20be%20closed')))),refreshInterval:(pause:!t,value:0),time:(from:now-30d%2Fd,to:now)))) By checking the [logs](https://buildkite.com/elastic/kibana-on-merge/builds/23841), it seems in these cases, it checks to see if the flyout is closed but for some reason, it is still open, so I added a retry based on @spalger 's suggestion. Flaky test runner[200]: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/1746 Flaky test runner[50]: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/1750 (After last commit) --- test/functional/services/flyout.ts | 11 +++++------ .../lib/web_element_wrapper/web_element_wrapper.ts | 1 + 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/functional/services/flyout.ts b/test/functional/services/flyout.ts index e7b57dc0fb66b..819fa7b480bc4 100644 --- a/test/functional/services/flyout.ts +++ b/test/functional/services/flyout.ts @@ -17,12 +17,11 @@ export class FlyoutService extends FtrService { public async close(dataTestSubj: string): Promise { this.log.debug('Closing flyout', dataTestSubj); const flyoutElement = await this.testSubjects.find(dataTestSubj); - const closeBtn = await flyoutElement.findByCssSelector('[aria-label*="Close"]'); - await closeBtn.click(); - await this.retry.waitFor( - 'flyout closed', - async () => !(await this.testSubjects.exists(dataTestSubj, { timeout: 1000 })) - ); + await this.retry.try(async () => { + const closeBtn = await flyoutElement.findByCssSelector('[aria-label*="Close"]'); + await closeBtn.click(); + await this.testSubjects.missingOrFail(dataTestSubj); + }); } public async ensureClosed(dataTestSubj: string): Promise { diff --git a/test/functional/services/lib/web_element_wrapper/web_element_wrapper.ts b/test/functional/services/lib/web_element_wrapper/web_element_wrapper.ts index 144b625121f7e..319a3b8b4ce03 100644 --- a/test/functional/services/lib/web_element_wrapper/web_element_wrapper.ts +++ b/test/functional/services/lib/web_element_wrapper/web_element_wrapper.ts @@ -466,6 +466,7 @@ export class WebElementWrapper { * @return {Promise} */ public async findByCssSelector(selector: string) { + this.logger.debug(`WebElementWrapper.findByCssSelector(${selector})`); return await this.retryCall(async function findByCssSelector(wrapper) { return wrapper._wrap( await wrapper._webElement.findElement(wrapper.By.css(selector)), From 881ab8554a4b84cb824e41547f365f792ba10a6c Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Wed, 18 Jan 2023 10:51:00 +0200 Subject: [PATCH 27/44] [Cases] Improve Jira mappings shows in the configuration page (#149012) ## Summary The configuration page shows how the case fields are mapped to the fields of the external service. Jira is the only connector that uses the case tags and mapped them to Jira labels. This PR updates Jira's mapping information shown to the users on the configuration page. Screenshot 2023-01-17 at 11 46 06 AM ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../cases/common/api/connectors/mappings.ts | 1 + .../cases/server/client/cases/utils.test.ts | 151 +++++++++++++++++- .../cases/server/client/cases/utils.ts | 6 +- .../cases/server/connectors/jira/mapping.ts | 5 + .../tests/common/configure/post_configure.ts | 5 + 5 files changed, 165 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/cases/common/api/connectors/mappings.ts b/x-pack/plugins/cases/common/api/connectors/mappings.ts index 8737a6c5a6462..33d7441c0c71f 100644 --- a/x-pack/plugins/cases/common/api/connectors/mappings.ts +++ b/x-pack/plugins/cases/common/api/connectors/mappings.ts @@ -16,6 +16,7 @@ const CaseFieldRT = rt.union([ rt.literal('title'), rt.literal('description'), rt.literal('comments'), + rt.literal('tags'), ]); const ThirdPartyFieldRT = rt.union([rt.string, rt.literal('not_mapped')]); diff --git a/x-pack/plugins/cases/server/client/cases/utils.test.ts b/x-pack/plugins/cases/server/client/cases/utils.test.ts index 9f34a52dae6a4..1e26a5783e8d9 100644 --- a/x-pack/plugins/cases/server/client/cases/utils.test.ts +++ b/x-pack/plugins/cases/server/client/cases/utils.test.ts @@ -88,7 +88,7 @@ describe('utils', () => { isDeprecated: false, }; - it('creates an external incident', async () => { + it('creates an external incident correctly for Jira', async () => { const res = await createIncident({ theCase, userActions: [], @@ -113,6 +113,155 @@ describe('utils', () => { }); }); + it('creates an external incident correctly for SN', async () => { + const snConnector = { + ...connector, + actionTypeId: '.servicenow', + }; + + const res = await createIncident({ + theCase, + userActions: [], + connector: snConnector, + alerts: [], + casesConnectors, + spaceId: 'default', + }); + + expect(res).toEqual({ + incident: { + category: null, + subcategory: null, + correlation_display: 'Elastic Case', + correlation_id: 'mock-id-1', + impact: null, + severity: null, + urgency: null, + short_description: 'Super Bad Security Issue', + description: + 'This is a brand new case of a bad meanie defacing data\n\nAdded by elastic.', + externalId: null, + }, + comments: [], + }); + }); + + it('creates an external incident correctly for SIR', async () => { + const snConnector = { + ...connector, + actionTypeId: '.servicenow-sir', + }; + + const res = await createIncident({ + theCase, + userActions: [], + connector: snConnector, + alerts: [], + casesConnectors, + spaceId: 'default', + }); + + expect(res).toEqual({ + incident: { + category: null, + subcategory: null, + correlation_display: 'Elastic Case', + correlation_id: 'mock-id-1', + dest_ip: [], + source_ip: [], + malware_hash: [], + malware_url: [], + priority: null, + short_description: 'Super Bad Security Issue', + description: + 'This is a brand new case of a bad meanie defacing data\n\nAdded by elastic.', + externalId: null, + }, + comments: [], + }); + }); + + it('creates an external incident correctly for IBM Resilient', async () => { + const resilientConnector = { + ...connector, + actionTypeId: '.resilient', + }; + + const res = await createIncident({ + theCase, + userActions: [], + connector: resilientConnector, + alerts: [], + casesConnectors, + spaceId: 'default', + }); + + expect(res).toEqual({ + incident: { + incidentTypes: null, + severityCode: null, + name: 'Super Bad Security Issue', + description: + 'This is a brand new case of a bad meanie defacing data\n\nAdded by elastic.', + externalId: null, + }, + comments: [], + }); + }); + + it('creates an external incident correctly for Swimlane', async () => { + const swimlaneConnector = { + ...connector, + actionTypeId: '.swimlane', + }; + + const res = await createIncident({ + theCase, + userActions: [], + connector: swimlaneConnector, + alerts: [], + casesConnectors, + spaceId: 'default', + }); + + expect(res).toEqual({ + incident: { + caseId: 'mock-id-1', + caseName: 'Super Bad Security Issue', + description: + 'This is a brand new case of a bad meanie defacing data\n\nAdded by elastic.', + externalId: null, + }, + comments: [], + }); + }); + + it('creates an external incident correctly for Cases webhook', async () => { + const webhookConnector = { + ...connector, + actionTypeId: '.cases-webhook', + }; + + const res = await createIncident({ + theCase, + userActions: [], + connector: webhookConnector, + alerts: [], + casesConnectors, + spaceId: 'default', + }); + + expect(res).toEqual({ + incident: { + externalId: null, + description: 'This is a brand new case of a bad meanie defacing data', + tags: ['defacement'], + title: 'Super Bad Security Issue', + }, + comments: [], + }); + }); + it('formats the connector fields correctly', async () => { const caseWithConnector = { ...flattenCaseSavedObject({ diff --git a/x-pack/plugins/cases/server/client/cases/utils.ts b/x-pack/plugins/cases/server/client/cases/utils.ts index e142493dff130..954b48cb2d1da 100644 --- a/x-pack/plugins/cases/server/client/cases/utils.ts +++ b/x-pack/plugins/cases/server/client/cases/utils.ts @@ -208,12 +208,14 @@ export const createIncident = async ({ }; export const mapCaseFieldsToExternalSystemFields = ( - caseFields: Record, unknown>, + caseFields: Record, unknown>, mapping: ConnectorMappingsAttributes[] ): Record => { const mappedCaseFields: Record = {}; - for (const caseFieldKey of Object.keys(caseFields) as Array>) { + for (const caseFieldKey of Object.keys(caseFields) as Array< + Exclude + >) { const mapDefinition = mapping.find( (mappingEntry) => mappingEntry.source === caseFieldKey && mappingEntry.target !== 'not_mapped' ); diff --git a/x-pack/plugins/cases/server/connectors/jira/mapping.ts b/x-pack/plugins/cases/server/connectors/jira/mapping.ts index 716a2694bdf1a..c3be1cc14fc45 100644 --- a/x-pack/plugins/cases/server/connectors/jira/mapping.ts +++ b/x-pack/plugins/cases/server/connectors/jira/mapping.ts @@ -19,6 +19,11 @@ export const getMapping: GetMapping = () => { target: 'description', action_type: 'overwrite', }, + { + source: 'tags', + target: 'labels', + action_type: 'overwrite', + }, { source: 'comments', target: 'comments', diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/configure/post_configure.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/configure/post_configure.ts index 47744830ec8b8..43cb5b21c978d 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/configure/post_configure.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/configure/post_configure.ts @@ -94,6 +94,11 @@ export default ({ getService }: FtrProviderContext): void => { source: 'description', target: 'description', }, + { + action_type: 'overwrite', + source: 'tags', + target: 'labels', + }, { action_type: 'append', source: 'comments', From aa66f9af6fdf4d7b751e1f41d8b87646cb62f469 Mon Sep 17 00:00:00 2001 From: Marco Liberati Date: Wed, 18 Jan 2023 10:34:04 +0100 Subject: [PATCH 28/44] [Lens] Automatically enable show array values for non-numeric runtime fields (#149025) ## Summary Fixes #148613 After investigating the issue via a different approach #149011 I've decided to handle it in this minimal way. This PR will automatically switch the `show_array` toggle for non numeric fields avoiding as much as possible direct appearance of the error to the user. If the user decides to explicitly disable the toggle, then the runtime error will be shown (the message there can still be improved). ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### Risk Matrix Delete this section if it is not applicable to this PR. Before closing this PR, invite QA, stakeholders, and other developers to identify risks that should be tested prior to the change/feature release. When forming the risk matrix, consider some of the following examples and how they may potentially impact the change: | Risk | Probability | Severity | Mitigation/Notes | |---------------------------|-------------|----------|-------------------------| | Multiple Spaces—unexpected behavior in non-default Kibana Space. | Low | High | Integration tests will verify that all features are still supported in non-default Kibana Space and when user switches between spaces. | | Multiple nodes—Elasticsearch polling might have race conditions when multiple Kibana nodes are polling for the same tasks. | High | Low | Tasks are idempotent, so executing them multiple times will not result in logical error, but will degrade performance. To test for this case we add plenty of unit tests around this logic and document manual testing procedure. | | Code should gracefully handle cases when feature X or plugin Y are disabled. | Medium | High | Unit tests will verify that any feature flag or plugin combination still results in our service operational. | | [See more potential risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) | ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../public/datasources/form_based/mocks.ts | 20 ++++++ .../formula/editor/math_completion.test.ts | 10 ++- .../definitions/last_value.test.tsx | 66 ++++++++++++++++++- .../operations/definitions/last_value.tsx | 17 ++++- .../operations/definitions/terms/helpers.ts | 4 ++ 5 files changed, 110 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/lens/public/datasources/form_based/mocks.ts b/x-pack/plugins/lens/public/datasources/form_based/mocks.ts index c2a85fbf0bac4..7ae9262f922ad 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/mocks.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/mocks.ts @@ -81,6 +81,26 @@ export const createMockedIndexPattern = (someProps?: Partial): Ind lang: 'painless' as const, script: '1234', }, + { + name: 'runtime-keyword', + displayName: 'Runtime keyword field', + type: 'string', + searchable: true, + aggregatable: true, + runtime: true, + lang: 'painless' as const, + script: 'emit("123")', + }, + { + name: 'runtime-number', + displayName: 'Runtime number field', + type: 'number', + searchable: true, + aggregatable: true, + runtime: true, + lang: 'painless' as const, + script: 'emit(123)', + }, ]; return { id: '1', diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/math_completion.test.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/math_completion.test.ts index bb91fc4a7b3ac..419208ec48d80 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/math_completion.test.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/math_completion.test.ts @@ -335,7 +335,7 @@ describe('math completion', () => { triggerCharacter: '(', }) ); - expect(results.list).toEqual(['bytes', 'memory']); + expect(results.list).toEqual(['bytes', 'memory', 'runtime-number']); }); it('should autocomplete only operations that provide numeric or date output', async () => { @@ -346,7 +346,13 @@ describe('math completion', () => { triggerCharacter: '(', }) ); - expect(results.list).toEqual(['bytes', 'memory', 'timestamp', 'start_date']); + expect(results.list).toEqual([ + 'bytes', + 'memory', + 'runtime-number', + 'timestamp', + 'start_date', + ]); }); it('should autocomplete shift parameter with relative suggestions and a couple of abs ones', async () => { diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.test.tsx index 104f6da48041f..5bd3aaada9a41 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.test.tsx @@ -290,6 +290,44 @@ describe('last_value', () => { ).params.showArrayValues ).toBeTruthy(); }); + + it('should set show array values if field is runtime and not of type number', () => { + const oldColumn: LastValueIndexPatternColumn = { + operationType: 'last_value', + sourceField: 'bytes', + label: 'Last value of bytes', + isBucketed: false, + dataType: 'number', + params: { + sortField: 'datefield', + showArrayValues: false, + }, + }; + const indexPattern = createMockedIndexPattern(); + const field = indexPattern.fields.find((i) => i.name === 'runtime-keyword')!; + + expect( + lastValueOperation.onFieldChange(oldColumn, field).params.showArrayValues + ).toBeTruthy(); + }); + + it('should not set show array values if field is runtime and of type number', () => { + const oldColumn: LastValueIndexPatternColumn = { + operationType: 'last_value', + sourceField: 'bytes', + label: 'Last value of bytes', + isBucketed: false, + dataType: 'number', + params: { + sortField: 'datefield', + showArrayValues: false, + }, + }; + const indexPattern = createMockedIndexPattern(); + const field = indexPattern.fields.find((i) => i.name === 'runtime-number')!; + + expect(lastValueOperation.onFieldChange(oldColumn, field).params.showArrayValues).toBeFalsy(); + }); }); describe('getPossibleOperationForField', () => { @@ -480,11 +518,19 @@ describe('last_value', () => { ); }); - it('should set showArrayValues if field is scripted or comes from existing params', () => { + it('should set showArrayValues if field is scripted, non-numeric runtime or comes from existing params', () => { const indexPattern = createMockedIndexPattern(); const scriptedField = indexPattern.fields.find((field) => field.scripted); - const nonScriptedField = indexPattern.fields.find((field) => !field.scripted); + const runtimeKeywordField = indexPattern.fields.find( + (field) => field.runtime && field.type !== 'number' + ); + const runtimeNumericField = indexPattern.fields.find( + (field) => field.runtime && field.type === 'number' + ); + const nonScriptedField = indexPattern.fields.find( + (field) => !field.scripted && !field.runtime + ); const localLayer = { columns: { @@ -508,6 +554,22 @@ describe('last_value', () => { }).params.showArrayValues ).toBeTruthy(); + expect( + lastValueOperation.buildColumn({ + indexPattern, + layer: localLayer, + field: runtimeKeywordField!, + }).params.showArrayValues + ).toBeTruthy(); + + expect( + lastValueOperation.buildColumn({ + indexPattern, + layer: localLayer, + field: runtimeNumericField!, + }).params.showArrayValues + ).toBeFalsy(); + expect( lastValueOperation.buildColumn( { diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.tsx index 698cdba8da13e..db9c7c0d6ab0c 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.tsx @@ -30,7 +30,7 @@ import { } from './helpers'; import { adjustTimeScaleLabelSuffix } from '../time_scale_utils'; import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils'; -import { isScriptedField } from './terms/helpers'; +import { isRuntimeField, isScriptedField } from './terms/helpers'; import { FormRow } from './shared_components/form_row'; import { getColumnReducedTimeRangeError } from '../../reduced_time_range_utils'; import { getGroupByKey } from './get_group_by_key'; @@ -107,6 +107,17 @@ function getDateFields(indexPattern: IndexPattern): IndexPatternField[] { return dateFields; } +function setDefaultShowArrayValues( + field: IndexPatternField, + oldParams: LastValueIndexPatternColumn['params'] +) { + return ( + isScriptedField(field) || + (isRuntimeField(field) && field.type !== 'number') || + oldParams?.showArrayValues + ); +} + export interface LastValueIndexPatternColumn extends FieldBasedIndexPatternColumn { operationType: 'last_value'; params: { @@ -154,7 +165,7 @@ export const lastValueOperation: OperationDefinition< onFieldChange: (oldColumn, field) => { const newParams = { ...oldColumn.params }; - newParams.showArrayValues = isScriptedField(field) || oldColumn.params.showArrayValues; + newParams.showArrayValues = setDefaultShowArrayValues(field, oldColumn.params); if ('format' in newParams && field.type !== 'number') { delete newParams.format; @@ -221,7 +232,7 @@ export const lastValueOperation: OperationDefinition< ); } - const showArrayValues = isScriptedField(field) || lastValueParams?.showArrayValues; + const showArrayValues = setDefaultShowArrayValues(field, lastValueParams); return { label: ofName(field.displayName, previousColumn?.timeShift, previousColumn?.reducedTimeRange), diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/helpers.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/helpers.ts index 27e6dc7b69d71..7b451445911df 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/helpers.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/helpers.ts @@ -265,6 +265,10 @@ export function isScriptedField( return fieldName.scripted; } +export function isRuntimeField(field: IndexPatternField): boolean { + return Boolean(field.runtime); +} + export function getFieldsByValidationState( newIndexPattern: IndexPattern, column?: GenericIndexPatternColumn, From 193636e85431a4ed86cb8a0ba77603e084d84187 Mon Sep 17 00:00:00 2001 From: Sander Philipse <94373878+sphilipse@users.noreply.github.com> Date: Wed, 18 Jan 2023 10:45:01 +0100 Subject: [PATCH 29/44] [Enterprise Search] Implement new feature toggle structure (#149033) ## Summary This updates our feature toggle structure to match the new contract. --- .../common/connectors/native_connectors.ts | 11 ++++++++++- .../common/types/connectors.ts | 18 ++++++++++++++++-- .../search_index/index_view_logic.ts | 10 ++++++++-- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/enterprise_search/common/connectors/native_connectors.ts b/x-pack/plugins/enterprise_search/common/connectors/native_connectors.ts index e2518ce9918b4..a19b1e2bb7c19 100644 --- a/x-pack/plugins/enterprise_search/common/connectors/native_connectors.ts +++ b/x-pack/plugins/enterprise_search/common/connectors/native_connectors.ts @@ -70,6 +70,10 @@ export const NATIVE_CONNECTOR_DEFINITIONS: Record | null; export interface Connector { api_key_id: string | null; configuration: ConnectorConfiguration; description: string | null; error: string | null; - features: Partial> | null; + features: ConnectorFeatures; filtering: FilteringConfig[]; id: string; index_name: string; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts index 2d3651a598fc1..26c1f823b479d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts @@ -197,12 +197,18 @@ export const IndexViewLogic = kea [selectors.connector], (connector?: Connector) => - connector?.features ? connector.features[FeatureName.FILTERING_ADVANCED_CONFIG] : false, + connector?.features + ? connector.features[FeatureName.SYNC_RULES]?.advanced?.enabled ?? + connector.features[FeatureName.FILTERING_ADVANCED_CONFIG] + : false, ], hasBasicFilteringFeature: [ () => [selectors.connector], (connector?: Connector) => - connector?.features ? connector.features[FeatureName.FILTERING_RULES] : false, + connector?.features + ? connector.features[FeatureName.SYNC_RULES]?.basic?.enabled ?? + connector.features[FeatureName.FILTERING_RULES] + : false, ], hasFilteringFeature: [ () => [selectors.hasAdvancedFilteringFeature, selectors.hasBasicFilteringFeature], From c9130c1467d52d39c273f13845be114ece84e721 Mon Sep 17 00:00:00 2001 From: Ievgen Sorokopud Date: Wed, 18 Jan 2023 11:33:09 +0100 Subject: [PATCH 30/44] [Security Solution][Alerts] Make rule preview flyout resizable (#147351) ## Summary This PR makes Rule Preview component resizable. https://user-images.githubusercontent.com/2700761/211618879-81be1065-09d0-4d9b-be41-04ba87e707c6.mov Closes #146847 Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../cypress/screens/create_new_rule.ts | 2 +- .../pages/rule_creation/index.tsx | 398 ++++++++++-------- .../pages/rule_editing/index.tsx | 208 +++++---- .../components/rules/rule_preview/index.tsx | 9 + .../rules/rule_preview/translations.ts | 15 + .../detection_engine/rules/preview/index.tsx | 84 ---- .../rules/preview/translations.ts | 30 -- .../detection_engine/rules/translations.ts | 8 - 8 files changed, 353 insertions(+), 401 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/preview/index.tsx delete mode 100644 x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/preview/translations.ts diff --git a/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts b/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts index 98c5df0bc8ea0..146f5d68d70e9 100644 --- a/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts +++ b/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts @@ -142,7 +142,7 @@ export const RISK_OVERRIDE = export const RULES_CREATION_FORM = '[data-test-subj="stepDefineRule"]'; -export const RULES_CREATION_PREVIEW_BUTTON = '[data-test-subj="preview-flyout"]'; +export const RULES_CREATION_PREVIEW_BUTTON = '[data-test-subj="preview-container"]'; export const RULES_CREATION_PREVIEW_REFRESH_BUTTON = '[data-test-subj="previewSubmitButton"]'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx index 9b2ebe46ce2d1..c1cf9ea2beb9c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx @@ -13,6 +13,7 @@ import { EuiPanel, EuiSpacer, EuiFlexGroup, + EuiResizableContainer, } from '@elastic/eui'; import React, { useCallback, useRef, useState, useMemo, useEffect } from 'react'; import styled from 'styled-components'; @@ -70,7 +71,7 @@ import { } from '../../../../../common/constants'; import { useKibana, useUiSetting$ } from '../../../../common/lib/kibana'; import { HeaderPage } from '../../../../common/components/header_page'; -import { PreviewFlyout } from '../../../../detections/pages/detection_engine/rules/preview'; +import { RulePreview } from '../../../../detections/components/rules/rule_preview'; import { useStartMlJobs } from '../../../rule_management/logic/use_start_ml_jobs'; const formHookNoop = async (): Promise => undefined; @@ -169,7 +170,8 @@ const CreateRulePageComponent: React.FC = () => { const actionMessageParams = useMemo(() => getActionMessageParams(ruleType), [ruleType]); const [dataViewOptions, setDataViewOptions] = useState<{ [x: string]: DataViewListItem }>({}); const [isPreviewDisabled, setIsPreviewDisabled] = useState(false); - const [isRulePreviewVisible, setIsRulePreviewVisible] = useState(false); + const [isRulePreviewVisible, setIsRulePreviewVisible] = useState(true); + const collapseFn = useRef<() => void | undefined>(); const [defineRuleData, setDefineRuleData] = useState({ ...stepDefineDefaultValue, @@ -384,190 +386,214 @@ const CreateRulePageComponent: React.FC = () => { return ( <> - - - - setIsRulePreviewVisible((isVisible) => !isVisible)} - > - {i18n.RULE_PREVIEW_TITLE} - - - - editStep(RuleStep.defineRule)} - > - {i18n.EDIT_RULE} - - ) - } - > - - submitStep(RuleStep.defineRule)} - kibanaDataViews={dataViewOptions} - descriptionColumns="singleSplit" - // We need a key to make this component remount when edit/view mode is toggled - // https://github.com/elastic/kibana/pull/132834#discussion_r881705566 - key={isShouldRerenderStep(RuleStep.defineRule, activeStep)} - indicesConfig={indicesConfig} - threatIndicesConfig={threatIndicesConfig} - onRuleDataChange={updateCurrentDataState} - onPreviewDisabledStateChange={setIsPreviewDisabled} - /> - - - - - editStep(RuleStep.aboutRule)} - > - {i18n.EDIT_RULE} - - ) - } - > - - submitStep(RuleStep.aboutRule)} - // We need a key to make this component remount when edit/view mode is toggled - // https://github.com/elastic/kibana/pull/132834#discussion_r881705566 - key={isShouldRerenderStep(RuleStep.aboutRule, activeStep)} - onRuleDataChange={updateCurrentDataState} - /> - - - - - editStep(RuleStep.scheduleRule)} - > - {i18n.EDIT_RULE} - - ) - } - > - - submitStep(RuleStep.scheduleRule)} - // We need a key to make this component remount when edit/view mode is toggled - // https://github.com/elastic/kibana/pull/132834#discussion_r881705566 - key={isShouldRerenderStep(RuleStep.scheduleRule, activeStep)} - onRuleDataChange={updateCurrentDataState} - /> - - - - - editStep(RuleStep.ruleActions)} - > - {i18n.EDIT_RULE} - - ) - } - > - - submitStep(RuleStep.ruleActions)} - actionMessageParams={actionMessageParams} - // We need a key to make this component remount when edit/view mode is toggled - // https://github.com/elastic/kibana/pull/132834#discussion_r881705566 - key={isShouldRerenderStep(RuleStep.ruleActions, activeStep)} - ruleType={ruleType} - /> - - - {isRulePreviewVisible && ( - setIsRulePreviewVisible(false)} - /> - )} - - + + {(EuiResizablePanel, EuiResizableButton, { togglePanel }) => { + collapseFn.current = () => togglePanel?.('preview', { direction: 'left' }); + return ( + <> + + + + + { + collapseFn.current?.(); + setIsRulePreviewVisible((isVisible) => !isVisible); + }} + > + {i18n.RULE_PREVIEW_TITLE} + + + + editStep(RuleStep.defineRule)} + > + {i18n.EDIT_RULE} + + ) + } + > + + submitStep(RuleStep.defineRule)} + kibanaDataViews={dataViewOptions} + descriptionColumns="singleSplit" + // We need a key to make this component remount when edit/view mode is toggled + // https://github.com/elastic/kibana/pull/132834#discussion_r881705566 + key={isShouldRerenderStep(RuleStep.defineRule, activeStep)} + indicesConfig={indicesConfig} + threatIndicesConfig={threatIndicesConfig} + onRuleDataChange={updateCurrentDataState} + onPreviewDisabledStateChange={setIsPreviewDisabled} + /> + + + + + editStep(RuleStep.aboutRule)} + > + {i18n.EDIT_RULE} + + ) + } + > + + submitStep(RuleStep.aboutRule)} + // We need a key to make this component remount when edit/view mode is toggled + // https://github.com/elastic/kibana/pull/132834#discussion_r881705566 + key={isShouldRerenderStep(RuleStep.aboutRule, activeStep)} + onRuleDataChange={updateCurrentDataState} + /> + + + + + editStep(RuleStep.scheduleRule)} + > + {i18n.EDIT_RULE} + + ) + } + > + + submitStep(RuleStep.scheduleRule)} + // We need a key to make this component remount when edit/view mode is toggled + // https://github.com/elastic/kibana/pull/132834#discussion_r881705566 + key={isShouldRerenderStep(RuleStep.scheduleRule, activeStep)} + onRuleDataChange={updateCurrentDataState} + /> + + + + + editStep(RuleStep.ruleActions)} + > + {i18n.EDIT_RULE} + + ) + } + > + + submitStep(RuleStep.ruleActions)} + actionMessageParams={actionMessageParams} + // We need a key to make this component remount when edit/view mode is toggled + // https://github.com/elastic/kibana/pull/132834#discussion_r881705566 + key={isShouldRerenderStep(RuleStep.ruleActions, activeStep)} + ruleType={ruleType} + /> + + + + + + + + + setIsRulePreviewVisible((isVisible) => !isVisible)} + > + + + + ); + }} + diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx index 78b58f95c91a0..63369244cc569 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx @@ -11,6 +11,7 @@ import { EuiCallOut, EuiFlexGroup, EuiFlexItem, + EuiResizableContainer, EuiSpacer, EuiTabbedContent, } from '@elastic/eui'; @@ -21,6 +22,7 @@ import { useParams } from 'react-router-dom'; import { noop } from 'lodash'; import type { DataViewListItem } from '@kbn/data-views-plugin/common'; +import { RulePreview } from '../../../../detections/components/rules/rule_preview'; import type { RuleUpdateProps } from '../../../../../common/detection_engine/rule_schema'; import { useRule, useUpdateRule } from '../../../rule_management/logic'; import { useListsConfig } from '../../../../detections/containers/detection_engine/lists/use_lists_config'; @@ -75,7 +77,6 @@ import { import { HeaderPage } from '../../../../common/components/header_page'; import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction'; import { SINGLE_RULE_ACTIONS } from '../../../../common/lib/apm/user_actions'; -import { PreviewFlyout } from '../../../../detections/pages/detection_engine/rules/preview'; import { useGetSavedQuery } from '../../../../detections/pages/detection_engine/rules/use_get_saved_query'; const formHookNoop = async (): Promise => undefined; @@ -129,7 +130,8 @@ const EditRulePageComponent: FC = () => { const { mutateAsync: updateRule, isLoading } = useUpdateRule(); const [dataViewOptions, setDataViewOptions] = useState<{ [x: string]: DataViewListItem }>({}); const [isPreviewDisabled, setIsPreviewDisabled] = useState(false); - const [isRulePreviewVisible, setIsRulePreviewVisible] = useState(false); + const [isRulePreviewVisible, setIsRulePreviewVisible] = useState(true); + const collapseFn = useRef<() => void | undefined>(); useEffect(() => { const fetchDataViews = async () => { @@ -197,8 +199,6 @@ const EditRulePageComponent: FC = () => { } }, [activeStep]); - const onPreviewClose = useCallback(() => setIsRulePreviewVisible(false), []); - const [indicesConfig] = useUiSetting$(DEFAULT_INDEX_KEY); const [threatIndicesConfig] = useUiSetting$(DEFAULT_THREAT_INDEX_KEY); @@ -464,99 +464,123 @@ const EditRulePageComponent: FC = () => { return ( <> - - - - {defineStep.data && aboutStep.data && scheduleStep.data && ( - setIsRulePreviewVisible((isVisible) => !isVisible)} - > - {ruleI18n.RULE_PREVIEW_TITLE} - - )} - - {invalidSteps.length > 0 && ( - - { - if (t === RuleStep.aboutRule) { - return ruleI18n.ABOUT; - } else if (t === RuleStep.defineRule) { - return ruleI18n.DEFINITION; - } else if (t === RuleStep.scheduleRule) { - return ruleI18n.SCHEDULE; - } else if (t === RuleStep.ruleActions) { - return ruleI18n.RULE_ACTIONS; - } - return t; - }) - .join(', '), - }} - /> - - )} + + {(EuiResizablePanel, EuiResizableButton, { togglePanel }) => { + collapseFn.current = () => togglePanel?.('preview', { direction: 'left' }); + return ( + <> + + + + + { + collapseFn.current?.(); + setIsRulePreviewVisible((isVisible) => !isVisible); + }} + > + {ruleI18n.RULE_PREVIEW_TITLE} + + + {invalidSteps.length > 0 && ( + + { + if (t === RuleStep.aboutRule) { + return ruleI18n.ABOUT; + } else if (t === RuleStep.defineRule) { + return ruleI18n.DEFINITION; + } else if (t === RuleStep.scheduleRule) { + return ruleI18n.SCHEDULE; + } else if (t === RuleStep.ruleActions) { + return ruleI18n.RULE_ACTIONS; + } + return t; + }) + .join(', '), + }} + /> + + )} - t.id === activeStep)} - onTabClick={onTabClick} - tabs={tabs} - /> + t.id === activeStep)} + onTabClick={onTabClick} + tabs={tabs} + /> - + - - - - {i18n.CANCEL} - - + + + + {i18n.CANCEL} + + - - + + {i18n.SAVE_CHANGES} + + + + + + + + + setIsRulePreviewVisible((isVisible) => !isVisible)} > - {i18n.SAVE_CHANGES} - -
    -
    - {isRulePreviewVisible && defineStep.data && aboutStep.data && scheduleStep.data && ( - - )} - -
    + {defineStep.data && aboutStep.data && scheduleStep.data && ( + + )} + + + ); + }} + diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/index.tsx index 64a60af8603c7..55931e74ff9d4 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/index.tsx @@ -16,6 +16,8 @@ import { EuiSpacer, EuiSuperDatePicker, EuiSuperUpdateButton, + EuiText, + EuiTitle, } from '@elastic/eui'; import moment from 'moment'; import type { List } from '@kbn/securitysolution-io-ts-list-types'; @@ -210,6 +212,13 @@ const RulePreviewComponent: React.FC = ({ return ( <> + +

    {i18n.RULE_PREVIEW_TITLE}

    +
    + + +

    {i18n.RULE_PREVIEW_DESCRIPTION}

    +
    {showInvocationCountWarning && ( <> diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/translations.ts b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/translations.ts index aff8b7dd37ac7..bd73aa2b3a27d 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/translations.ts @@ -163,3 +163,18 @@ export const VIEW_DETAILS_FOR_ROW = ({ defaultMessage: 'View details for the alert or event in row {ariaRowindex}, with columns {columnValues}', }); + +export const RULE_PREVIEW_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.rulePreviewTitle', + { + defaultMessage: 'Rule preview', + } +); + +export const RULE_PREVIEW_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.rulePreviewDescription', + { + defaultMessage: + 'Rule preview reflects the current configuration of your rule settings and exceptions, click refresh icon to see the updated preview.', + } +); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/preview/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/preview/index.tsx deleted file mode 100644 index 405fec71af954..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/preview/index.tsx +++ /dev/null @@ -1,84 +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. - */ - -import { - EuiButton, - EuiSpacer, - EuiFlyout, - EuiFlyoutBody, - EuiFlyoutFooter, - EuiFlyoutHeader, - EuiText, - EuiTitle, -} from '@elastic/eui'; -import React from 'react'; -import styled from 'styled-components'; - -import type { List } from '@kbn/securitysolution-io-ts-list-types'; -import { RulePreview } from '../../../../components/rules/rule_preview'; -import type { AboutStepRule, DefineStepRule, ScheduleStepRule } from '../types'; - -import * as i18n from './translations'; - -const StyledEuiFlyout = styled(EuiFlyout)` - clip-path: none; -`; - -const StyledEuiFlyoutBody = styled(EuiFlyoutBody)` - overflow-y: hidden; - flex: 1; - - .euiFlyoutBody__overflow { - mask-image: none; - } -`; - -interface PreviewFlyoutProps { - isDisabled: boolean; - defineStepData: DefineStepRule; - aboutStepData: AboutStepRule; - scheduleStepData: ScheduleStepRule; - exceptionsList?: List[]; - onClose: () => void; -} - -const PreviewFlyoutComponent: React.FC = ({ - isDisabled, - defineStepData, - aboutStepData, - scheduleStepData, - exceptionsList, - onClose, -}) => { - return ( - - - -

    {i18n.RULE_PREVIEW_TITLE}

    -
    - - -

    {i18n.RULE_PREVIEW_DESCRIPTION}

    -
    -
    - - - - - {i18n.CANCEL_BUTTON_LABEL} - -
    - ); -}; - -export const PreviewFlyout = React.memo(PreviewFlyoutComponent); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/preview/translations.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/preview/translations.ts deleted file mode 100644 index 9e3e3af9fd6a1..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/preview/translations.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const RULE_PREVIEW_TITLE = i18n.translate( - 'xpack.securitySolution.detectionEngine.createRule.rulePreviewTitle', - { - defaultMessage: 'Rule preview', - } -); - -export const RULE_PREVIEW_DESCRIPTION = i18n.translate( - 'xpack.securitySolution.detectionEngine.createRule.rulePreviewDescription', - { - defaultMessage: - 'Rule preview reflects the current configuration of your rule settings and exceptions, click refresh icon to see the updated preview.', - } -); - -export const CANCEL_BUTTON_LABEL = i18n.translate( - 'xpack.securitySolution.detectionEngine.createRule.cancelButtonLabel', - { - defaultMessage: 'Cancel', - } -); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts index 78d8f9ebee3e6..e734b9b384ff9 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts @@ -1114,14 +1114,6 @@ export const RULE_PREVIEW_TITLE = i18n.translate( } ); -export const RULE_PREVIEW_DESCRIPTION = i18n.translate( - 'xpack.securitySolution.detectionEngine.createRule.rulePreviewDescription', - { - defaultMessage: - 'Rule preview reflects the current configuration of your rule settings and exceptions, click refresh icon to see the updated preview.', - } -); - export const CANCEL_BUTTON_LABEL = i18n.translate( 'xpack.securitySolution.detectionEngine.createRule.cancelButtonLabel', { From bbf19cab6e35f0c2eed7e399a9546de7d8c6e31f Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Wed, 18 Jan 2023 12:03:23 +0100 Subject: [PATCH 31/44] [Saved Objects] Browser-side client deprecation notice (#148979) ## Summary In the near future we will remove Saved Object (SO) HTTP APIs. This PR deprecates all browser-side SO types and interfaces. General comments on the approach taken here: * Add a deprecation notice that links to a GitHub issue that can be referenced by all teams * Do not break existing imports/exports * Mocks are also an indication of SO browser-side use, added deprecation notices * Some common types must also be deprecated, some may remain. For those to be removed they are moved to a separate file, with a deprecated type-alias re-exported ## Notes to reviewers * Easiest way to get an overview of the changes is to have the file-tree open in the "Files changed" view * Are there any other ways browser-side code can get knowledge of Saved Objects? * Please go through some client code and test that the DX is working as expected (the GitHub issue is discoverable) ## Related * https://github.com/elastic/kibana/issues/147150 * https://github.com/elastic/dev/issues/2194 Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../src/apis/base.ts | 1 + .../src/apis/bulk_create.ts | 2 + .../src/apis/bulk_delete.ts | 3 + .../src/apis/bulk_resolve.ts | 1 + .../src/apis/bulk_update.ts | 2 + .../src/apis/create.ts | 1 + .../src/apis/delete.ts | 1 + .../src/apis/find.ts | 2 + .../src/apis/resolve.ts | 1 + .../src/apis/update.ts | 1 + .../src/saved_objects_client.ts | 1 + .../src/simple_saved_object.ts | 1 + .../src/saved_objects_client.ts | 1 + .../src/saved_objects_service.ts | 3 + .../src/simple_saved_object.ts | 1 + .../src/saved_objects_service.mock.ts | 3 + .../src/simple_saved_object.mock.ts | 3 + .../src/contracts.ts | 1 + .../src/saved_objects.ts | 107 +++++------------- .../src/server_types.ts | 94 +++++++++++++++ .../core-saved-objects-server/index.ts | 7 ++ 21 files changed, 161 insertions(+), 76 deletions(-) create mode 100644 packages/core/saved-objects/core-saved-objects-common/src/server_types.ts diff --git a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/base.ts b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/base.ts index 74d5223def315..451e2551f08eb 100644 --- a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/base.ts +++ b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/base.ts @@ -12,6 +12,7 @@ import { SimpleSavedObject } from '../simple_saved_object'; * Batch response for simple saved objects * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export interface SavedObjectsBatchResponse { /** Array of simple saved objects */ diff --git a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_create.ts b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_create.ts index 6d5ce23205ef8..bc925b35647a3 100644 --- a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_create.ts +++ b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_create.ts @@ -12,6 +12,7 @@ import type { SavedObjectsCreateOptions } from './create'; * Per-object parameters for bulk create operation * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export interface SavedObjectsBulkCreateObject extends SavedObjectsCreateOptions { /** Create a SavedObject of this type. */ @@ -24,6 +25,7 @@ export interface SavedObjectsBulkCreateObject extends SavedObjectsC * Options for bulk create operation * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 * */ export interface SavedObjectsBulkCreateOptions { /** If a document with the given `id` already exists, overwrite its contents (default=false). */ diff --git a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_delete.ts b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_delete.ts index 532e900338d8a..4744cc406e97b 100644 --- a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_delete.ts +++ b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_delete.ts @@ -12,6 +12,7 @@ import { SavedObjectError } from '@kbn/core-saved-objects-common'; * Options for bulk delete operation * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export interface SavedObjectsBulkDeleteOptions { /** Force deletion of any objects that exist in multiple namespaces (default=false) */ @@ -22,6 +23,7 @@ export interface SavedObjectsBulkDeleteOptions { * Single item within the statuses array of the bulk delete response * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export interface SavedObjectsBulkDeleteResponseItem { /** saved object id */ @@ -38,6 +40,7 @@ export interface SavedObjectsBulkDeleteResponseItem { * Return type of the Saved Objects `bulkDelete()` method. * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export interface SavedObjectsBulkDeleteResponse { /** array of statuses per object */ diff --git a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_resolve.ts b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_resolve.ts index c5ba482525298..8b24e32f5791c 100644 --- a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_resolve.ts +++ b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_resolve.ts @@ -12,6 +12,7 @@ import type { ResolvedSimpleSavedObject } from './resolve'; * Return type of the Saved Objects `bulkResolve()` method. * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export interface SavedObjectsBulkResolveResponse { /** Array of {@link ResolvedSimpleSavedObject} that were resolved */ diff --git a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_update.ts b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_update.ts index c819fb1ac448d..56f516a37e9df 100644 --- a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_update.ts +++ b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_update.ts @@ -12,6 +12,7 @@ import type { SavedObjectReference } from '@kbn/core-saved-objects-common'; * Per-object parameters for bulk update operation * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export interface SavedObjectsBulkUpdateObject { /** Type of the saved object to update */ @@ -30,6 +31,7 @@ export interface SavedObjectsBulkUpdateObject { * Options for bulk update operation * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 * */ export interface SavedObjectsBulkUpdateOptions { /** diff --git a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/create.ts b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/create.ts index fb6a18219e5bf..65242b1bda546 100644 --- a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/create.ts +++ b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/create.ts @@ -15,6 +15,7 @@ import type { * Options for creating a saved object. * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export interface SavedObjectsCreateOptions { /** diff --git a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/delete.ts b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/delete.ts index c43dbec6845b3..e25038acf27cc 100644 --- a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/delete.ts +++ b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/delete.ts @@ -10,6 +10,7 @@ * Options for deleting a saved object. * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export interface SavedObjectsDeleteOptions { /** Force deletion of an object that exists in multiple namespaces (default=false) */ diff --git a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/find.ts b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/find.ts index 39d99a6ee6e86..9048b2b54308d 100644 --- a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/find.ts +++ b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/find.ts @@ -15,6 +15,7 @@ export type { SavedObjectsFindOptionsReference } from '@kbn/core-saved-objects-a * Browser options for finding saved objects * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export type SavedObjectsFindOptions = Omit< SavedObjectFindOptionsServer, @@ -25,6 +26,7 @@ export type SavedObjectsFindOptions = Omit< * Return type of the Saved Objects `find()` method. * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export interface SavedObjectsFindResponse extends SavedObjectsBatchResponse { diff --git a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/resolve.ts b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/resolve.ts index d2868ae48ced1..53ffe7782c720 100644 --- a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/resolve.ts +++ b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/resolve.ts @@ -14,6 +14,7 @@ import type { SimpleSavedObject } from '../simple_saved_object'; * with the {@link SavedObjectsClientContract}. * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export interface ResolvedSimpleSavedObject { /** diff --git a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/update.ts b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/update.ts index f8095e35df1e5..e456c5b9c6ea6 100644 --- a/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/update.ts +++ b/packages/core/saved-objects/core-saved-objects-api-browser/src/apis/update.ts @@ -12,6 +12,7 @@ import type { SavedObjectReference } from '@kbn/core-saved-objects-common'; * Options for updating a saved object * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export interface SavedObjectsUpdateOptions { /** version of the saved object */ diff --git a/packages/core/saved-objects/core-saved-objects-api-browser/src/saved_objects_client.ts b/packages/core/saved-objects/core-saved-objects-api-browser/src/saved_objects_client.ts index 9ff01104c5ba0..0011b6df7342e 100644 --- a/packages/core/saved-objects/core-saved-objects-api-browser/src/saved_objects_client.ts +++ b/packages/core/saved-objects/core-saved-objects-api-browser/src/saved_objects_client.ts @@ -30,6 +30,7 @@ import type { SimpleSavedObject } from './simple_saved_object'; * HTTP API for interacting with Saved Objects. * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export interface SavedObjectsClientContract { /** diff --git a/packages/core/saved-objects/core-saved-objects-api-browser/src/simple_saved_object.ts b/packages/core/saved-objects/core-saved-objects-api-browser/src/simple_saved_object.ts index 2932d4f5675a8..57bad2bc1b226 100644 --- a/packages/core/saved-objects/core-saved-objects-api-browser/src/simple_saved_object.ts +++ b/packages/core/saved-objects/core-saved-objects-api-browser/src/simple_saved_object.ts @@ -16,6 +16,7 @@ import type { SavedObject as SavedObjectType } from '@kbn/core-saved-objects-com * but doesn't include any type-specific implementations. * * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export interface SimpleSavedObject { /** attributes of the object, templated */ diff --git a/packages/core/saved-objects/core-saved-objects-browser-internal/src/saved_objects_client.ts b/packages/core/saved-objects/core-saved-objects-browser-internal/src/saved_objects_client.ts index 1fd111186f551..d7f9b8a8b4d0b 100644 --- a/packages/core/saved-objects/core-saved-objects-browser-internal/src/saved_objects_client.ts +++ b/packages/core/saved-objects/core-saved-objects-browser-internal/src/saved_objects_client.ts @@ -104,6 +104,7 @@ const getObjectsToResolve = (queue: BatchResolveQueueEntry[]) => { * HTTP API for interacting with Saved Objects. * * @internal + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export class SavedObjectsClient implements SavedObjectsClientContract { private http: HttpSetup; diff --git a/packages/core/saved-objects/core-saved-objects-browser-internal/src/saved_objects_service.ts b/packages/core/saved-objects/core-saved-objects-browser-internal/src/saved_objects_service.ts index 111d98bfcc126..7cef8a1c39057 100644 --- a/packages/core/saved-objects/core-saved-objects-browser-internal/src/saved_objects_service.ts +++ b/packages/core/saved-objects/core-saved-objects-browser-internal/src/saved_objects_service.ts @@ -11,6 +11,9 @@ import type { HttpStart } from '@kbn/core-http-browser'; import type { SavedObjectsStart } from '@kbn/core-saved-objects-browser'; import { SavedObjectsClient } from './saved_objects_client'; +/** + * @deprecated See https://github.com/elastic/kibana/issues/149098 + */ export class SavedObjectsService implements CoreService { public async setup() {} diff --git a/packages/core/saved-objects/core-saved-objects-browser-internal/src/simple_saved_object.ts b/packages/core/saved-objects/core-saved-objects-browser-internal/src/simple_saved_object.ts index 414ed5bbf1846..8c5fc18129761 100644 --- a/packages/core/saved-objects/core-saved-objects-browser-internal/src/simple_saved_object.ts +++ b/packages/core/saved-objects/core-saved-objects-browser-internal/src/simple_saved_object.ts @@ -18,6 +18,7 @@ import type { * Core internal implementation of {@link SimpleSavedObject} * * @internal Should use the {@link SimpleSavedObject} interface instead + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export class SimpleSavedObjectImpl implements SimpleSavedObject { public attributes: T; diff --git a/packages/core/saved-objects/core-saved-objects-browser-mocks/src/saved_objects_service.mock.ts b/packages/core/saved-objects/core-saved-objects-browser-mocks/src/saved_objects_service.mock.ts index 2239b94d7e2eb..3b537311d72d9 100644 --- a/packages/core/saved-objects/core-saved-objects-browser-mocks/src/saved_objects_service.mock.ts +++ b/packages/core/saved-objects/core-saved-objects-browser-mocks/src/saved_objects_service.mock.ts @@ -41,6 +41,9 @@ const createMock = () => { return mocked; }; +/** + * @deprecated See https://github.com/elastic/kibana/issues/149098 + */ export const savedObjectsServiceMock = { create: createMock, createStartContract: createStartContractMock, diff --git a/packages/core/saved-objects/core-saved-objects-browser-mocks/src/simple_saved_object.mock.ts b/packages/core/saved-objects/core-saved-objects-browser-mocks/src/simple_saved_object.mock.ts index 2e3c30ac17d9c..8264b5fd6ba87 100644 --- a/packages/core/saved-objects/core-saved-objects-browser-mocks/src/simple_saved_object.mock.ts +++ b/packages/core/saved-objects/core-saved-objects-browser-mocks/src/simple_saved_object.mock.ts @@ -63,6 +63,9 @@ const createSimpleSavedObjectMock = ( return mock; }; +/** + * @deprecated See https://github.com/elastic/kibana/issues/149098 + */ export const simpleSavedObjectMock = { create: (client: SavedObjectsClientContract, savedObject: SavedObject) => createSimpleSavedObjectMock(savedObject), diff --git a/packages/core/saved-objects/core-saved-objects-browser/src/contracts.ts b/packages/core/saved-objects/core-saved-objects-browser/src/contracts.ts index c372f3169ed80..082893e6efc74 100644 --- a/packages/core/saved-objects/core-saved-objects-browser/src/contracts.ts +++ b/packages/core/saved-objects/core-saved-objects-browser/src/contracts.ts @@ -9,6 +9,7 @@ import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-bro /** * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 */ export interface SavedObjectsStart { /** {@link SavedObjectsClientContract} */ diff --git a/packages/core/saved-objects/core-saved-objects-common/src/saved_objects.ts b/packages/core/saved-objects/core-saved-objects-common/src/saved_objects.ts index b9ea336d349bd..12e554cf185c8 100644 --- a/packages/core/saved-objects/core-saved-objects-common/src/saved_objects.ts +++ b/packages/core/saved-objects/core-saved-objects-common/src/saved_objects.ts @@ -6,47 +6,7 @@ * Side Public License, v 1. */ -/** - * Don't use this type, it's simply a helper type for {@link SavedObjectAttribute} - * - * @public - */ -export type SavedObjectAttributeSingle = - | string - | number - | boolean - | null - | undefined - | SavedObjectAttributes; - -/** - * Type definition for a Saved Object attribute value - * - * @public - */ -export type SavedObjectAttribute = SavedObjectAttributeSingle | SavedObjectAttributeSingle[]; - -/** - * The data for a Saved Object is stored as an object in the `attributes` - * property. - * - * @public - * @deprecated This type reduces the type safety of your code. Create an interface for your specific saved object type or use `unknown` instead. - */ -export interface SavedObjectAttributes { - [key: string]: SavedObjectAttribute; -} - -/** - * A reference to another saved object. - * - * @public - */ -export interface SavedObjectReference { - name: string; - type: string; - id: string; -} +import * as serverTypes from './server_types'; /** * Information about the migrations that have been applied to this SavedObject. @@ -68,41 +28,6 @@ export interface SavedObjectsMigrationVersion { [pluginName: string]: string; } -export interface SavedObject { - /** The ID of this Saved Object, guaranteed to be unique for all objects of the same `type` */ - id: string; - /** The type of Saved Object. Each plugin can define it's own custom Saved Object types. */ - type: string; - /** An opaque version number which changes on each successful write operation. Can be used for implementing optimistic concurrency control. */ - version?: string; - /** Timestamp of the time this document had been created. */ - created_at?: string; - /** Timestamp of the last time this document had been updated. */ - updated_at?: string; - /** Error associated with this object, populated if an operation failed for this object. */ - error?: SavedObjectError; - /** The data for a Saved Object is stored as an object in the `attributes` property. **/ - attributes: T; - /** {@inheritdoc SavedObjectReference} */ - references: SavedObjectReference[]; - /** {@inheritdoc SavedObjectsMigrationVersion} */ - migrationVersion?: SavedObjectsMigrationVersion; - /** A semver value that is used when upgrading objects between Kibana versions. */ - coreMigrationVersion?: string; - /** - * Space(s) that this saved object exists in. This attribute is not used for "global" saved object types which are registered with - * `namespaceType: 'agnostic'`. - */ - namespaces?: string[]; - /** - * The ID of the saved object this originated from. This is set if this object's `id` was regenerated; that can happen during migration - * from a legacy single-namespace type, or during import. It is only set during migration or create operations. This is used during import - * to ensure that ID regeneration is deterministic, so saved objects will be overwritten if they are imported multiple times into a given - * space. - */ - originId?: string; -} - /** * The namespace type dictates how a saved object can be interacted in relation to namespaces. Each type is mutually exclusive: * * single (default): This type of saved object is namespace-isolated, e.g., it exists in only one namespace. @@ -123,3 +48,33 @@ export interface SavedObjectError { statusCode: number; metadata?: Record; } + +/** + * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 + */ +export type SavedObjectAttributeSingle = serverTypes.SavedObjectAttributeSingle; + +/** + * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 + */ +export type SavedObjectAttribute = serverTypes.SavedObjectAttribute; + +/** + * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 + */ +export type SavedObjectAttributes = serverTypes.SavedObjectAttributes; + +/** + * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 + */ +export type SavedObjectReference = serverTypes.SavedObjectReference; + +/** + * @public + * @deprecated See https://github.com/elastic/kibana/issues/149098 + */ +export type SavedObject = serverTypes.SavedObject; diff --git a/packages/core/saved-objects/core-saved-objects-common/src/server_types.ts b/packages/core/saved-objects/core-saved-objects-common/src/server_types.ts new file mode 100644 index 0000000000000..8b0ae5c819952 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-common/src/server_types.ts @@ -0,0 +1,94 @@ +/* + * 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. + */ + +/** + * Note: this file contains types that are intended for use by server-side code + * only. Once the Saved Objects client is removed from browser code we will + * remove these types as well. + * + * See https://github.com/elastic/kibana/issues/149098. + */ + +import type { SavedObjectsMigrationVersion, SavedObjectError } from './saved_objects'; + +/** + * Don't use this type, it's simply a helper type for {@link SavedObjectAttribute} + * + * @public + */ +export type SavedObjectAttributeSingle = + | string + | number + | boolean + | null + | undefined + | SavedObjectAttributes; + +/** + * Type definition for a Saved Object attribute value + * + * @public + */ +export type SavedObjectAttribute = SavedObjectAttributeSingle | SavedObjectAttributeSingle[]; + +/** + * The data for a Saved Object is stored as an object in the `attributes` + * property. + * + * @public + * @deprecated This type reduces the type safety of your code. Create an interface for your specific saved object type or use `unknown` instead. + */ +export interface SavedObjectAttributes { + [key: string]: SavedObjectAttribute; +} + +/** + * A reference to another saved object. + * + * @public + */ +export interface SavedObjectReference { + name: string; + type: string; + id: string; +} + +export interface SavedObject { + /** The ID of this Saved Object, guaranteed to be unique for all objects of the same `type` */ + id: string; + /** The type of Saved Object. Each plugin can define it's own custom Saved Object types. */ + type: string; + /** An opaque version number which changes on each successful write operation. Can be used for implementing optimistic concurrency control. */ + version?: string; + /** Timestamp of the time this document had been created. */ + created_at?: string; + /** Timestamp of the last time this document had been updated. */ + updated_at?: string; + /** Error associated with this object, populated if an operation failed for this object. */ + error?: SavedObjectError; + /** The data for a Saved Object is stored as an object in the `attributes` property. **/ + attributes: T; + /** {@inheritdoc SavedObjectReference} */ + references: SavedObjectReference[]; + /** {@inheritdoc SavedObjectsMigrationVersion} */ + migrationVersion?: SavedObjectsMigrationVersion; + /** A semver value that is used when upgrading objects between Kibana versions. */ + coreMigrationVersion?: string; + /** + * Space(s) that this saved object exists in. This attribute is not used for "global" saved object types which are registered with + * `namespaceType: 'agnostic'`. + */ + namespaces?: string[]; + /** + * The ID of the saved object this originated from. This is set if this object's `id` was regenerated; that can happen during migration + * from a legacy single-namespace type, or during import. It is only set during migration or create operations. This is used during import + * to ensure that ID regeneration is deterministic, so saved objects will be overwritten if they are imported multiple times into a given + * space. + */ + originId?: string; +} diff --git a/packages/core/saved-objects/core-saved-objects-server/index.ts b/packages/core/saved-objects/core-saved-objects-server/index.ts index f8791a1efbe5a..f99a813d01b7d 100644 --- a/packages/core/saved-objects/core-saved-objects-server/index.ts +++ b/packages/core/saved-objects/core-saved-objects-server/index.ts @@ -89,3 +89,10 @@ export { SECURITY_EXTENSION_ID, SPACES_EXTENSION_ID, } from './src/extensions/extensions'; + +export type { + SavedObject, + SavedObjectAttribute, + SavedObjectAttributeSingle, + SavedObjectReference, +} from '@kbn/core-saved-objects-common/src/server_types'; From a5e14cd2d71a1515216f20b840d2f6086c88dd92 Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Wed, 18 Jan 2023 12:23:39 +0100 Subject: [PATCH 32/44] [AO] Add AlertSummaryWidget full-size on the Alerts page (#148539) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves #148279 ## 📝 Summary Add AlertSummaryWidget full-size on the Alerts page. ![image](https://user-images.githubusercontent.com/12370520/211568369-7d0847ba-e90e-4229-a55a-b68bf55209f8.png) **Note** The functional test will be added in another ticket (https://github.com/elastic/kibana/issues/148645) ## 🧪 How to test - Create a rule that generates an alert and go to the observability > alerts page, you should see the number of alerts correctly in the Alert Summary Widget - Change the time range to see different formats in the tooltip and the number of buckets will also change accordingly ## 🐛 Known issue When we don't have any rule, the `_alert_summary` API fails and we show a failed message, I will discuss it with @XavierM, and based on the decision, either I'll update this PR or create a separate PR. Update: I created a ticket for it (https://github.com/elastic/kibana/issues/148653) Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../containers/alerts_page/alerts_page.tsx | 73 ++++++++++++++++--- .../get_alert_summary_time_range.test.tsx | 63 ++++++++++++++-- .../helpers/get_alert_summary_time_range.tsx | 36 ++++++++- .../pages/rule_details/helpers/index.ts | 5 +- .../public/pages/rule_details/index.tsx | 6 +- .../public/utils/get_bucket_size/index.ts | 4 +- .../server/routes/get_alert_summary.test.ts | 2 +- .../server/routes/get_alert_summary.ts | 4 +- .../hooks/use_load_alert_summary.ts | 20 ++--- .../mock/alert_summary_widget/index.ts | 2 +- .../alert_summary/alert_summary_widget.tsx | 1 + .../components/alert_state_info.tsx | 2 +- .../alert_summary_widget_compact.tsx | 4 +- .../alert_summary_widget_full_size.tsx | 7 +- .../alert_summary/components/constants.tsx | 2 +- .../components/alert_summary/types.ts | 15 +++- .../triggers_actions_ui/public/index.ts | 1 + .../triggers_actions_ui/public/types.ts | 2 + 18 files changed, 197 insertions(+), 52 deletions(-) diff --git a/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx index e2a6915fd79b6..fdbee30ce12cc 100644 --- a/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx @@ -5,15 +5,25 @@ * 2.0. */ -import { EuiFlexGroup, EuiFlexItem, EuiFlyoutSize } from '@elastic/eui'; - import React, { useEffect, useState } from 'react'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { TimeBuckets, UI_SETTINGS } from '@kbn/data-plugin/common'; import { BoolQuery } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { loadRuleAggregations } from '@kbn/triggers-actions-ui-plugin/public'; +import { + loadRuleAggregations, + AlertSummaryTimeRange, +} from '@kbn/triggers-actions-ui-plugin/public'; import { AlertConsumers } from '@kbn/rule-data-utils'; -import { ObservabilityAlertSearchbarWithUrlSync } from '../../../../components/shared/alert_search_bar'; +import { useToasts } from '../../../../hooks/use_toast'; +import { + alertSearchBarStateContainer, + Provider, + useAlertSearchBarStateContainer, +} from '../../../../components/shared/alert_search_bar/containers'; +import { getAlertSummaryTimeRange } from '../../../rule_details/helpers'; +import { ObservabilityAlertSearchBar } from '../../../../components/shared/alert_search_bar'; import { observabilityAlertFeatureIds } from '../../../../config'; import { useGetUserCasesPermissions } from '../../../../hooks/use_get_user_cases_permissions'; import { observabilityFeatureId } from '../../../../../common'; @@ -33,15 +43,27 @@ import { } from './constants'; import { RuleStatsState } from './types'; -export function AlertsPage() { +function InternalAlertsPage() { const { ObservabilityPageTemplate, observabilityRuleTypeRegistry } = usePluginContext(); const { cases, + data: { + query: { + timefilter: { timefilter: timeFilterService }, + }, + }, docLinks, http, notifications: { toasts }, - triggersActionsUi: { alertsTableConfigurationRegistry, getAlertsStateTable: AlertsStateTable }, + triggersActionsUi: { + alertsTableConfigurationRegistry, + getAlertsSearchBar: AlertsSearchBar, + getAlertsStateTable: AlertsStateTable, + getAlertSummaryWidget: AlertSummaryWidget, + }, + uiSettings, } = useKibana().services; + const alertSearchBarStateProps = useAlertSearchBarStateContainer(URL_STORAGE_KEY); const [ruleStatsLoading, setRuleStatsLoading] = useState(false); const [ruleStats, setRuleStats] = useState({ @@ -53,6 +75,19 @@ export function AlertsPage() { }); const { hasAnyData, isAllRequestsComplete } = useHasData(); const [esQuery, setEsQuery] = useState<{ bool: BoolQuery }>(); + const timeBuckets = new TimeBuckets({ + 'histogram:maxBars': uiSettings.get(UI_SETTINGS.HISTOGRAM_MAX_BARS), + 'histogram:barTarget': uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET), + dateFormat: uiSettings.get('dateFormat'), + 'dateFormat:scaled': uiSettings.get('dateFormat:scaled'), + }); + const alertSummaryTimeRange: AlertSummaryTimeRange = getAlertSummaryTimeRange( + { + from: alertSearchBarStateProps.rangeFrom, + to: alertSearchBarStateProps.rangeTo, + }, + timeBuckets + ); useBreadcrumbs([ { @@ -132,15 +167,23 @@ export function AlertsPage() { rightSideItems: renderRuleStats(ruleStats, manageRulesHref, ruleStatsLoading), }} > - + - + + + - ); } + +export function AlertsPage() { + return ( + + + + ); +} diff --git a/x-pack/plugins/observability/public/pages/rule_details/helpers/get_alert_summary_time_range.test.tsx b/x-pack/plugins/observability/public/pages/rule_details/helpers/get_alert_summary_time_range.test.tsx index 9c437f5f5da64..d63cce34755c1 100644 --- a/x-pack/plugins/observability/public/pages/rule_details/helpers/get_alert_summary_time_range.test.tsx +++ b/x-pack/plugins/observability/public/pages/rule_details/helpers/get_alert_summary_time_range.test.tsx @@ -6,14 +6,63 @@ */ import moment from 'moment'; -import { getAlertSummaryWidgetTimeRange } from '.'; +import { TimeBuckets } from '@kbn/data-plugin/common'; +import { getAlertSummaryTimeRange, getDefaultAlertSummaryTimeRange } from '.'; -describe('getDefaultAlertSummaryTimeRange', () => { - it('should return default time in UTC format', () => { - const defaultTimeRange = getAlertSummaryWidgetTimeRange(); - const utcFormat = 'YYYY-MM-DDTHH:mm:ss.SSSZ'; +describe('AlertSummaryTimeRange', () => { + describe('getDefaultAlertSummaryTimeRange', () => { + it('should return default time in UTC format', () => { + const defaultTimeRange = getDefaultAlertSummaryTimeRange(); + const utcFormat = 'YYYY-MM-DDTHH:mm:ss.SSSZ'; - expect(moment(defaultTimeRange.utcFrom, utcFormat, true).isValid()).toBeTruthy(); - expect(moment(defaultTimeRange.utcTo, utcFormat, true).isValid()).toBeTruthy(); + expect(moment(defaultTimeRange.utcFrom, utcFormat, true).isValid()).toBeTruthy(); + expect(moment(defaultTimeRange.utcTo, utcFormat, true).isValid()).toBeTruthy(); + }); + }); + + describe('getAlertSummaryTimeRange', () => { + const timeBucketConfig = { + 'histogram:maxBars': 4, + 'histogram:barTarget': 3, + dateFormat: 'YYYY-MM-DD', + 'dateFormat:scaled': [ + ['', 'HH:mm:ss.SSS'], + ['PT1S', 'HH:mm:ss'], + ['PT1M', 'HH:mm'], + ['PT1H', 'YYYY-MM-DD HH:mm'], + ['P1DT', 'YYYY-MM-DD'], + ['P1YT', 'YYYY'], + ], + }; + const timeBuckets = new TimeBuckets(timeBucketConfig); + + it.each([ + // 15 minutes + ['2023-01-09T12:07:54.441Z', '2023-01-09T12:22:54.441Z', '30s', 'HH:mm:ss'], + // 30 minutes + ['2023-01-09T11:53:43.605Z', '2023-01-09T12:23:43.605Z', '30s', 'HH:mm:ss'], + // 1 hour + ['2023-01-09T11:22:05.728Z', '2023-01-09T12:22:05.728Z', '60s', 'HH:mm'], + // 24 hours + ['2023-01-08T12:00:00.000Z', '2023-01-09T12:24:30.853Z', '1800s', 'HH:mm'], + // 7 days + ['2023-01-01T23:00:00.000Z', '2023-01-09T12:29:38.101Z', '10800s', 'YYYY-MM-DD HH:mm'], + // 30 days + ['2022-12-09T23:00:00.000Z', '2023-01-09T12:30:13.717Z', '43200s', 'YYYY-MM-DD HH:mm'], + // 90 days + ['2022-10-10T22:00:00.000Z', '2023-01-09T12:32:11.537Z', '86400s', 'YYYY-MM-DD'], + // 1 year + ['2022-01-08T23:00:00.000Z', '2023-01-09T12:33:09.906Z', '86400s', 'YYYY-MM-DD'], + ])( + `Input: [%s, %s], Output: interval: %s, time format: %s `, + (from, to, fixedInterval, dateFormat) => { + expect(getAlertSummaryTimeRange({ from, to }, timeBuckets)).toEqual({ + utcFrom: from, + utcTo: to, + fixedInterval, + dateFormat, + }); + } + ); }); }); diff --git a/x-pack/plugins/observability/public/pages/rule_details/helpers/get_alert_summary_time_range.tsx b/x-pack/plugins/observability/public/pages/rule_details/helpers/get_alert_summary_time_range.tsx index 973bfc628ea60..decfa03fb6f8c 100644 --- a/x-pack/plugins/observability/public/pages/rule_details/helpers/get_alert_summary_time_range.tsx +++ b/x-pack/plugins/observability/public/pages/rule_details/helpers/get_alert_summary_time_range.tsx @@ -5,12 +5,15 @@ * 2.0. */ -import type { AlertSummaryTimeRange } from '@kbn/triggers-actions-ui-plugin/public/application/hooks/use_load_alert_summary'; import React from 'react'; -import { getAbsoluteTimeRange } from '@kbn/data-plugin/common'; +import { getAbsoluteTimeRange, TimeBuckets } from '@kbn/data-plugin/common'; +import { TimeRange } from '@kbn/es-query'; import { FormattedMessage } from '@kbn/i18n-react'; +import type { AlertSummaryTimeRange } from '@kbn/triggers-actions-ui-plugin/public'; +import { getAbsoluteTime } from '../../../utils/date'; +import { getBucketSize } from '../../../utils/get_bucket_size'; -export const getAlertSummaryWidgetTimeRange = (): AlertSummaryTimeRange => { +export const getDefaultAlertSummaryTimeRange = (): AlertSummaryTimeRange => { const { to, from } = getAbsoluteTimeRange({ from: 'now-30d', to: 'now', @@ -28,3 +31,30 @@ export const getAlertSummaryWidgetTimeRange = (): AlertSummaryTimeRange => { ), }; }; + +export const getAlertSummaryTimeRange = ( + timeRange: TimeRange, + timeBuckets: TimeBuckets +): AlertSummaryTimeRange => { + const { to, from } = getAbsoluteTimeRange(timeRange); + const fixedInterval = getFixedInterval(timeRange); + timeBuckets.setInterval(fixedInterval); + + return { + utcFrom: from, + utcTo: to, + fixedInterval, + dateFormat: timeBuckets.getScaledDateFormat(), + }; +}; + +const getFixedInterval = ({ to, from }: TimeRange) => { + const start = getAbsoluteTime(from); + const end = getAbsoluteTime(to, { roundUp: true }); + + if (start && end) { + return getBucketSize({ start, end, minInterval: '30s', buckets: 60 }).intervalString; + } + + return '1m'; +}; diff --git a/x-pack/plugins/observability/public/pages/rule_details/helpers/index.ts b/x-pack/plugins/observability/public/pages/rule_details/helpers/index.ts index e93f2f4cc5ee0..5ba979bf5a0fe 100644 --- a/x-pack/plugins/observability/public/pages/rule_details/helpers/index.ts +++ b/x-pack/plugins/observability/public/pages/rule_details/helpers/index.ts @@ -5,4 +5,7 @@ * 2.0. */ -export { getAlertSummaryWidgetTimeRange } from './get_alert_summary_time_range'; +export { + getDefaultAlertSummaryTimeRange, + getAlertSummaryTimeRange, +} from './get_alert_summary_time_range'; diff --git a/x-pack/plugins/observability/public/pages/rule_details/index.tsx b/x-pack/plugins/observability/public/pages/rule_details/index.tsx index 420757b7b50bd..fa8c2273b0ac0 100644 --- a/x-pack/plugins/observability/public/pages/rule_details/index.tsx +++ b/x-pack/plugins/observability/public/pages/rule_details/index.tsx @@ -42,7 +42,7 @@ import { fromQuery, toQuery } from '../../utils/url'; import { ObservabilityAlertSearchbarWithUrlSync } from '../../components/shared/alert_search_bar'; import { DeleteModalConfirmation } from './components/delete_modal_confirmation'; import { CenterJustifiedSpinner } from './components/center_justified_spinner'; -import { getAlertSummaryWidgetTimeRange } from './helpers'; +import { getDefaultAlertSummaryTimeRange } from './helpers'; import { EXECUTION_TAB, @@ -112,7 +112,7 @@ export function RuleDetailsPage() { const [isRuleEditPopoverOpen, setIsRuleEditPopoverOpen] = useState(false); const [esQuery, setEsQuery] = useState<{ bool: BoolQuery }>(); const [alertSummaryWidgetTimeRange, setAlertSummaryWidgetTimeRange] = useState( - getAlertSummaryWidgetTimeRange + getDefaultAlertSummaryTimeRange ); const ruleQuery = useRef([ { query: `kibana.alert.rule.uuid: ${ruleId}`, language: 'kuery' }, @@ -125,7 +125,7 @@ export function RuleDetailsPage() { const tabsRef = useRef(null); const onAlertSummaryWidgetClick = async (status: AlertStatus = ALERT_STATUS_ALL) => { - const timeRange = getAlertSummaryWidgetTimeRange(); + const timeRange = getDefaultAlertSummaryTimeRange(); setAlertSummaryWidgetTimeRange(timeRange); await locators.get(ruleDetailsLocatorID)?.navigate( { diff --git a/x-pack/plugins/observability/public/utils/get_bucket_size/index.ts b/x-pack/plugins/observability/public/utils/get_bucket_size/index.ts index 495fc766cd62f..ca1afaf41c1a6 100644 --- a/x-pack/plugins/observability/public/utils/get_bucket_size/index.ts +++ b/x-pack/plugins/observability/public/utils/get_bucket_size/index.ts @@ -14,13 +14,15 @@ export function getBucketSize({ start, end, minInterval, + buckets = 100, }: { start: number; end: number; minInterval: string; + buckets?: number; }) { const duration = moment.duration(end - start, 'ms'); - const bucketSize = Math.max(calculateAuto.near(100, duration)?.asSeconds() ?? 0, 1); + const bucketSize = Math.max(calculateAuto.near(buckets, duration)?.asSeconds() ?? 0, 1); const intervalString = `${bucketSize}s`; const matches = minInterval && minInterval.match(/^([\d]+)([shmdwMy]|ms)$/); const minBucketSize = matches ? Number(matches[1]) * unitToSeconds(matches[2]) : 0; diff --git a/x-pack/plugins/rule_registry/server/routes/get_alert_summary.test.ts b/x-pack/plugins/rule_registry/server/routes/get_alert_summary.test.ts index 3496b8f342e2c..e15f2d40dc826 100644 --- a/x-pack/plugins/rule_registry/server/routes/get_alert_summary.test.ts +++ b/x-pack/plugins/rule_registry/server/routes/get_alert_summary.test.ts @@ -88,7 +88,7 @@ describe('getAlertSummaryRoute', () => { "attributes": Object { "success": false, }, - "message": "fixed_interval is not following the expected format 1m, 1h, 1d, 1w", + "message": "fixed_interval (value: xx) is not following the expected format 1s, 1m, 1h, 1d with at most 6 digits", } `); }); diff --git a/x-pack/plugins/rule_registry/server/routes/get_alert_summary.ts b/x-pack/plugins/rule_registry/server/routes/get_alert_summary.ts index 6125c2a39b845..838bf06e7e768 100644 --- a/x-pack/plugins/rule_registry/server/routes/get_alert_summary.ts +++ b/x-pack/plugins/rule_registry/server/routes/get_alert_summary.ts @@ -57,9 +57,9 @@ export const getAlertSummaryRoute = (router: IRouter) throw Boom.badRequest('gte and/or lte are not following the UTC format'); } - if (fixedInterval && fixedInterval?.match(/^\d{1,2}['m','h','d','w']$/) == null) { + if (fixedInterval && fixedInterval?.match(/^\d{1,6}['s','m','h','d']$/) == null) { throw Boom.badRequest( - 'fixed_interval is not following the expected format 1m, 1h, 1d, 1w' + `fixed_interval (value: ${fixedInterval}) is not following the expected format 1s, 1m, 1h, 1d with at most 6 digits` ); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_alert_summary.ts b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_alert_summary.ts index 25c670d787a09..e3dbeb2a3b525 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_alert_summary.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_alert_summary.ts @@ -12,19 +12,10 @@ import { AsApiContract } from '@kbn/actions-plugin/common'; import { HttpSetup } from '@kbn/core/public'; import { BASE_RAC_ALERTS_API_PATH } from '@kbn/rule-registry-plugin/common/constants'; import { useKibana } from '../../common/lib/kibana'; - -export interface AlertSummaryTimeRange { - utcFrom: string; - utcTo: string; - // fixed_interval condition in ES query such as '1m', '1d' - fixedInterval: string; - title: JSX.Element | string; -} - -export interface Alert { - key: number; - doc_count: number; -} +import { + Alert, + AlertSummaryTimeRange, +} from '../sections/rule_details/components/alert_summary/types'; interface UseLoadAlertSummaryProps { featureIds?: ValidFeatureId[]; @@ -75,8 +66,7 @@ export function useLoadAlertSummary({ featureIds, timeRange, filter }: UseLoadAl }); if (!isCancelledRef.current) { - setAlertSummary((oldState) => ({ - ...oldState, + setAlertSummary(() => ({ alertSummary: { activeAlertCount, activeAlerts, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/mock/alert_summary_widget/index.ts b/x-pack/plugins/triggers_actions_ui/public/application/mock/alert_summary_widget/index.ts index aaeb820ff136b..9dbd13c9c8011 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/mock/alert_summary_widget/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/mock/alert_summary_widget/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { AlertSummaryTimeRange } from '../../hooks/use_load_alert_summary'; +import { AlertSummaryTimeRange } from '../../sections/rule_details/components/alert_summary/types'; export const mockAlertSummaryResponse = { activeAlertCount: 2, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/alert_summary_widget.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/alert_summary_widget.tsx index 5232eb2661966..0ecb70d1a478b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/alert_summary_widget.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/alert_summary_widget.tsx @@ -41,6 +41,7 @@ export const AlertSummaryWidget = ({ activeAlerts={activeAlerts} recoveredAlertCount={recoveredAlertCount} recoveredAlerts={recoveredAlerts} + dateFormat={timeRange.dateFormat} /> ) : ( void; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/components/alert_summary_widget_full_size.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/components/alert_summary_widget_full_size.tsx index 4d8d7cc564e22..d338cd3a0668b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/components/alert_summary_widget_full_size.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/alert_summary/components/alert_summary_widget_full_size.tsx @@ -23,13 +23,14 @@ import { RECOVERED_COLOR, TOOLTIP_DATE_FORMAT, } from './constants'; -import { Alert } from '../../../../../hooks/use_load_alert_summary'; +import { Alert } from '../types'; export interface AlertsSummaryWidgetFullSizeProps { activeAlertCount: number; activeAlerts: Alert[]; recoveredAlertCount: number; recoveredAlerts: Alert[]; + dateFormat?: string; } export const AlertsSummaryWidgetFullSize = ({ @@ -37,6 +38,7 @@ export const AlertsSummaryWidgetFullSize = ({ activeAlerts, recoveredAlertCount, recoveredAlerts, + dateFormat, }: AlertsSummaryWidgetFullSizeProps) => { const isDarkMode = useUiSetting('theme:darkMode'); const { euiTheme } = useEuiTheme(); @@ -106,7 +108,8 @@ export const AlertsSummaryWidgetFullSize = ({ // TODO Use the EUI charts theme https://github.com/elastic/kibana/issues/148297 theme={chartTheme} tooltip={{ - headerFormatter: (tooltip) => moment(tooltip.value).format(TOOLTIP_DATE_FORMAT), + headerFormatter: (tooltip) => + moment(tooltip.value).format(dateFormat || TOOLTIP_DATE_FORMAT), }} /> Date: Wed, 18 Jan 2023 13:11:02 +0100 Subject: [PATCH 33/44] [Synthetics] Add location in view test run button (#149106) --- .../monitor_details/monitor_summary/last_test_run.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/last_test_run.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/last_test_run.tsx index b3aa2e129dc81..e4c886df23d61 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/last_test_run.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/last_test_run.tsx @@ -22,6 +22,7 @@ import { import { i18n } from '@kbn/i18n'; import { useParams } from 'react-router-dom'; +import { getTestRunDetailLink } from '../../common/links/test_details_link'; import { useSelectedLocation } from '../hooks/use_selected_location'; import { getErrorDetailsUrl } from '../monitor_errors/errors_list'; import { @@ -148,6 +149,8 @@ const PanelHeader = ({ const { basePath } = useSyntheticsSettingsContext(); + const selectedLocation = useSelectedLocation(); + const { monitorId } = useParams<{ monitorId: string }>(); const format = useKibanaDateFormat(); @@ -208,7 +211,12 @@ const PanelHeader = ({ size="xs" iconType="inspect" iconSide="left" - href={`${basePath}/app/synthetics/monitor/${monitorId}/test-run/${latestPing?.monitor.check_group}`} + href={getTestRunDetailLink({ + basePath, + monitorId, + checkGroup: latestPing?.monitor.check_group, + locationId: selectedLocation?.id, + })} > {i18n.translate('xpack.synthetics.monitorDetails.summary.viewTestRun', { defaultMessage: 'View test run', From 1f3b40ae322593253f8530c173e7b13ac02bf86d Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 18 Jan 2023 14:36:16 +0200 Subject: [PATCH 34/44] [Lens] Displays mosaic and waffle on suggestions (#149000) ## Summary Closes https://github.com/elastic/kibana/issues/120505 Now that both mosaic and waffle are on GA, we should show them to the the suggestions. Reverted the changes of the PR mentioned on the issue. image ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios Co-authored-by: Marco Liberati --- .../partition/suggestions.test.ts | 79 ++++++++++++++++++- .../visualizations/partition/suggestions.ts | 14 +++- 2 files changed, 86 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/lens/public/visualizations/partition/suggestions.test.ts b/x-pack/plugins/lens/public/visualizations/partition/suggestions.test.ts index 0be4fbde6c1d2..95f35f6f21cc2 100644 --- a/x-pack/plugins/lens/public/visualizations/partition/suggestions.test.ts +++ b/x-pack/plugins/lens/public/visualizations/partition/suggestions.test.ts @@ -992,7 +992,7 @@ describe('suggestions', () => { expect(suggs[0].state.layers[0].allowMultipleMetrics).toBeFalsy(); }); - it('mosaic type should be hidden from the suggestion list', () => { + it('mosaic type should be shown in the suggestion list', () => { expect( suggestions({ table: { @@ -1012,6 +1012,7 @@ describe('suggestions', () => { operation: { label: 'Count', dataType: 'number' as DataType, isBucketed: false }, }, ], + changeType: 'unchanged', }, state: { @@ -1035,7 +1036,43 @@ describe('suggestions', () => { }, keptLayerIds: ['first'], }).filter(({ hide, state }) => !hide && state.shape === 'mosaic') - ).toMatchInlineSnapshot(`Array []`); + ).toMatchInlineSnapshot(` + Array [ + Object { + "hide": false, + "previewIcon": "bullseye", + "score": 0.61, + "state": Object { + "layers": Array [ + Object { + "allowMultipleMetrics": false, + "categoryDisplay": "default", + "layerId": "first", + "layerType": "data", + "legendDisplay": "show", + "legendMaxLines": 1, + "metrics": Array [ + "c", + ], + "nestedLegend": true, + "numberDisplay": "hidden", + "percentDecimals": 0, + "primaryGroups": Array [ + "a", + ], + "secondaryGroups": Array [ + "b", + ], + "truncateLegend": true, + }, + ], + "palette": undefined, + "shape": "mosaic", + }, + "title": "As Mosaic", + }, + ] + `); }); }); @@ -1069,7 +1106,7 @@ describe('suggestions', () => { ).toHaveLength(0); }); - it('waffle type should be hidden from the suggestion list', () => { + it('waffle type should be shown in the suggestion list', () => { expect( suggestions({ table: { @@ -1085,6 +1122,7 @@ describe('suggestions', () => { operation: { label: 'Count', dataType: 'number' as DataType, isBucketed: false }, }, ], + changeType: 'unchanged', }, state: { @@ -1107,7 +1145,40 @@ describe('suggestions', () => { }, keptLayerIds: ['first'], }).filter(({ hide, state }) => !hide && state.shape === 'waffle') - ).toMatchInlineSnapshot(`Array []`); + ).toMatchInlineSnapshot(` + Array [ + Object { + "hide": false, + "previewIcon": "bullseye", + "score": 0.46, + "state": Object { + "layers": Array [ + Object { + "categoryDisplay": "default", + "layerId": "first", + "layerType": "data", + "legendDisplay": "show", + "legendMaxLines": 1, + "metrics": Array [ + "b", + ], + "nestedLegend": true, + "numberDisplay": "hidden", + "percentDecimals": 0, + "primaryGroups": Array [ + "a", + ], + "secondaryGroups": Array [], + "truncateLegend": true, + }, + ], + "palette": undefined, + "shape": "waffle", + }, + "title": "As Waffle", + }, + ] + `); }); }); }); diff --git a/x-pack/plugins/lens/public/visualizations/partition/suggestions.ts b/x-pack/plugins/lens/public/visualizations/partition/suggestions.ts index 93887559a094e..05def4e0a2937 100644 --- a/x-pack/plugins/lens/public/visualizations/partition/suggestions.ts +++ b/x-pack/plugins/lens/public/visualizations/partition/suggestions.ts @@ -267,7 +267,11 @@ export function suggestions({ ], }, previewIcon: 'bullseye', - hide: true, + hide: + groups.length !== 2 || + table.changeType === 'reduced' || + hasIntervalScale(groups) || + (state && state.shape === 'mosaic'), }); } @@ -279,7 +283,7 @@ export function suggestions({ title: i18n.translate('xpack.lens.pie.waffleSuggestionLabel', { defaultMessage: 'As Waffle', }), - score: state?.shape === PieChartTypes.WAFFLE ? 0.7 : 0.5, + score: state?.shape === PieChartTypes.WAFFLE ? 0.7 : 0.4, state: { shape: PieChartTypes.WAFFLE, palette: mainPalette || state?.palette, @@ -307,7 +311,11 @@ export function suggestions({ ], }, previewIcon: 'bullseye', - hide: true, + hide: + groups.length !== 1 || + table.changeType === 'reduced' || + hasIntervalScale(groups) || + (state && state.shape === 'waffle'), }); } From 9f35e1ea3f712b96c0733f0828c5a877ae972636 Mon Sep 17 00:00:00 2001 From: Yngrid Coello Date: Wed, 18 Jan 2023 13:41:25 +0100 Subject: [PATCH 35/44] scenarioOpts example (#149111) Added an example of how to use `--scenarioOpts` --- packages/kbn-apm-synthtrace/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/kbn-apm-synthtrace/README.md b/packages/kbn-apm-synthtrace/README.md index 27ace45288298..6a6d0b726a5e4 100644 --- a/packages/kbn-apm-synthtrace/README.md +++ b/packages/kbn-apm-synthtrace/README.md @@ -139,6 +139,7 @@ Note: - The default `--to` is `15m`. - You can combine `--from` and `--to` with `--live` to back-fill some data. +- To specify `--scenarioOpts` you need to use [yargs Objects syntax](https://github.com/yargs/yargs/blob/HEAD/docs/tricks.md#objects). (e.g. --scenarioOpts.myOption=myValue) ### Setup options From f190904e9d8a692d25508b3466c8c4db502320e0 Mon Sep 17 00:00:00 2001 From: Joseph McElroy Date: Wed, 18 Jan 2023 12:59:30 +0000 Subject: [PATCH 36/44] [Behavioral Analytics] update documentation + update link to events doc (#148881) Update documentation + links to analytics events page ![image](https://user-images.githubusercontent.com/49480/212310925-bc07c2c1-602a-404a-85bb-1061f977d081.png) --- packages/kbn-doc-links/src/get_doc_links.ts | 1 + packages/kbn-doc-links/src/types.ts | 1 + ...lytics_collection_integrate_javascript_embed.tsx | 13 ++++++++++--- .../applications/shared/doc_links/doc_links.ts | 3 +++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/kbn-doc-links/src/get_doc_links.ts b/packages/kbn-doc-links/src/get_doc_links.ts index 24462ed7274e4..6406e0c635a28 100644 --- a/packages/kbn-doc-links/src/get_doc_links.ts +++ b/packages/kbn-doc-links/src/get_doc_links.ts @@ -124,6 +124,7 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => { }, enterpriseSearch: { apiKeys: `${KIBANA_DOCS}api-keys.html`, + behavioralAnalyticsEvents: `${ENTERPRISE_SEARCH_DOCS}analytics-events.html`, bulkApi: `${ELASTICSEARCH_DOCS}docs-bulk.html`, configuration: `${ENTERPRISE_SEARCH_DOCS}configuration.html`, connectors: `${ENTERPRISE_SEARCH_DOCS}connectors.html`, diff --git a/packages/kbn-doc-links/src/types.ts b/packages/kbn-doc-links/src/types.ts index beebf4739028f..1d771c8c89647 100644 --- a/packages/kbn-doc-links/src/types.ts +++ b/packages/kbn-doc-links/src/types.ts @@ -109,6 +109,7 @@ export interface DocLinks { }; readonly enterpriseSearch: { readonly apiKeys: string; + readonly behavioralAnalyticsEvents: string; readonly bulkApi: string; readonly configuration: string; readonly connectors: string; diff --git a/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate/analytics_collection_integrate_javascript_embed.tsx b/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate/analytics_collection_integrate_javascript_embed.tsx index 0cd91a14b4e21..425912d8166e6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate/analytics_collection_integrate_javascript_embed.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate/analytics_collection_integrate_javascript_embed.tsx @@ -12,6 +12,8 @@ import { EuiCodeBlock, EuiLink, EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; +import { docLinks } from '../../../../shared/doc_links'; + export const javascriptEmbedSteps = (webClientSrc: string, analyticsDNSUrl: string) => [ { title: i18n.translate( @@ -82,7 +84,7 @@ export const javascriptEmbedSteps = (webClientSrc: string, analyticsDNSUrl: stri values={{ link: (

    - - {``} + + {`window.elasticAnalytics.trackEvent("click", { + category: "product", + action: "add_to_cart", + label: "product_id", + value: "123" +});`} diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/doc_links/doc_links.ts b/x-pack/plugins/enterprise_search/public/applications/shared/doc_links/doc_links.ts index 4b391a70076ec..cc1356fc0c140 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/doc_links/doc_links.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/doc_links/doc_links.ts @@ -34,6 +34,7 @@ class DocLinks { public appSearchWebCrawler: string; public appSearchWebCrawlerEventLogs: string; public appSearchWebCrawlerReference: string; + public behavioralAnalyticsEvents: string; public bulkApi: string; public clientsGoIndex: string; public clientsGuide: string; @@ -148,6 +149,7 @@ class DocLinks { this.appSearchWebCrawler = ''; this.appSearchWebCrawlerEventLogs = ''; this.appSearchWebCrawlerReference = ''; + this.behavioralAnalyticsEvents = ''; this.bulkApi = ''; this.clientsGoIndex = ''; this.clientsGuide = ''; @@ -264,6 +266,7 @@ class DocLinks { this.appSearchWebCrawler = docLinks.links.appSearch.webCrawler; this.appSearchWebCrawlerEventLogs = docLinks.links.appSearch.webCrawlerEventLogs; this.appSearchWebCrawlerReference = docLinks.links.appSearch.webCrawlerReference; + this.behavioralAnalyticsEvents = docLinks.links.enterpriseSearch.behavioralAnalyticsEvents; this.bulkApi = docLinks.links.enterpriseSearch.bulkApi; this.clientsGoIndex = docLinks.links.clients.goIndex; this.clientsGuide = docLinks.links.clients.guide; From 635f72f5924779d8b8f135286815a89671966d92 Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Wed, 18 Jan 2023 14:17:22 +0100 Subject: [PATCH 37/44] [Fleet] changed telemetry log to debug (#149107) ## Summary Closes https://github.com/elastic/kibana/issues/148060 Changed telemetry log to debug if `.fleet-agents` index does not exist, so it is not flagging error/warning. --- x-pack/plugins/fleet/server/services/agents/status.ts | 2 +- x-pack/plugins/fleet/server/services/fleet_usage_logger.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/agents/status.ts b/x-pack/plugins/fleet/server/services/agents/status.ts index 77babf8c8c19c..d05d972925eb5 100644 --- a/x-pack/plugins/fleet/server/services/agents/status.ts +++ b/x-pack/plugins/fleet/server/services/agents/status.ts @@ -108,7 +108,7 @@ export async function getAgentStatusForAgentPolicy( }, }); } catch (error) { - logger.warn(`Error getting agent statuses: ${error}`); + logger.debug(`Error getting agent statuses: ${error}`); throw error; } diff --git a/x-pack/plugins/fleet/server/services/fleet_usage_logger.ts b/x-pack/plugins/fleet/server/services/fleet_usage_logger.ts index d1f6a0f5aba36..92a1dc6da33cf 100644 --- a/x-pack/plugins/fleet/server/services/fleet_usage_logger.ts +++ b/x-pack/plugins/fleet/server/services/fleet_usage_logger.ts @@ -39,7 +39,7 @@ export async function registerFleetUsageLogger( } catch (error) { appContextService .getLogger() - .warn('Error occurred while fetching fleet usage: ' + error); + .debug('Error occurred while fetching fleet usage: ' + error); } }, From 52f7e6e458c1ae8863fb452f2c62fa5e0f921888 Mon Sep 17 00:00:00 2001 From: Abdul Wahab Zahid Date: Wed, 18 Jan 2023 14:23:29 +0100 Subject: [PATCH 38/44] [Synthetics] Monitor Management - Add Project ID and update Monitor Type badges (#149023) (#148994) Closes https://github.com/elastic/kibana/issues/148994 ## Summary - Adds the Project ID column and removes the icon in front of project monitors as per new design. - Updates monitor type badges as per new design. - Clicking a location badge will navigate to monitor details page for that location. image --- .../synthetics_overview_status.ts | 1 + .../synthetics/management_list.journey.ts | 49 +++++++----- .../components/location_status_badges.tsx | 64 ++++++++++++--- .../components/monitor_details_panel.tsx | 9 +-- .../common/components/monitor_type_badge.tsx | 78 +++++++++++++++++++ .../common/components/tag_badges.tsx | 6 +- .../monitor_summary/locations_status.tsx | 2 +- .../management/monitor_list_table/columns.tsx | 33 ++++++-- .../management/monitor_list_table/labels.tsx | 17 ++-- .../monitor_details_link.tsx | 26 +------ .../monitor_list_table/monitor_enabled.tsx | 8 +- .../monitor_list_table/monitor_locations.tsx | 4 +- .../monitor_stats/monitor_stats.tsx | 1 + .../overview/actions_popover.test.tsx | 2 +- .../overview/overview/actions_popover.tsx | 2 +- .../overview/monitor_detail_flyout.test.tsx | 2 +- .../overview/monitor_detail_flyout.tsx | 2 +- .../hooks/use_monitor_detail_locator.ts | 2 +- .../status_rule/status_rule_executor.ts | 10 ++- .../server/queries/query_monitor_status.ts | 7 +- .../synthetics/server/routes/common.ts | 13 +++- .../server/routes/status/current_status.ts | 9 ++- 22 files changed, 253 insertions(+), 94 deletions(-) create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_type_badge.tsx rename x-pack/plugins/synthetics/public/apps/synthetics/{components/monitors_page => }/hooks/use_monitor_detail_locator.ts (93%) diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts index 06252f2b56703..d5c49bbe84058 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts @@ -20,6 +20,7 @@ export const OverviewStatusMetaDataCodec = t.interface({ export const OverviewStatusCodec = t.interface({ allMonitorsCount: t.number, disabledMonitorsCount: t.number, + projectMonitorsCount: t.number, up: t.number, down: t.number, disabledCount: t.number, diff --git a/x-pack/plugins/synthetics/e2e/journeys/synthetics/management_list.journey.ts b/x-pack/plugins/synthetics/e2e/journeys/synthetics/management_list.journey.ts index eaf1bc78241f0..ad220cbc20ded 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/synthetics/management_list.journey.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/synthetics/management_list.journey.ts @@ -7,6 +7,7 @@ import { journey, step, expect, before, after } from '@elastic/synthetics'; import { recordVideo } from '@kbn/observability-plugin/e2e/record_video'; +import { byTestId } from '@kbn/ux-plugin/e2e/journeys/utils'; import { addTestMonitor, cleanTestMonitors, @@ -22,6 +23,11 @@ journey(`MonitorManagementList`, async ({ page, params }) => { const testMonitor2 = 'Test monitor 2'; const testMonitor3 = 'Test monitor 3'; + const pageBaseUrl = 'http://localhost:5620/app/synthetics/monitors'; + const searchBarInput = page.locator( + '[placeholder="Search by name, url, host, tag, project or location"]' + ); + page.setDefaultTimeout(60 * 1000); before(async () => { @@ -48,19 +54,14 @@ journey(`MonitorManagementList`, async ({ page, params }) => { }); step('shows the count', async () => { - await page.locator('text=Monitors'); - await page.click('text=1-3'); + await page.waitForSelector('text=Monitors'); + await page.waitForSelector('text=1-3'); }); - step( - 'Click text=Showing 1-3 of 3 ConfigurationsSortingThis table contains 3 rows out of 3 rows; Page 1', - async () => { - await page.click( - 'text=Showing 1-3 of 3 ConfigurationsSortingThis table contains 3 rows out of 3 rows; Page 1' - ); - await page.click('[aria-label="expands filter group for Type filter"]'); - } - ); + step('Click text=Showing 1-3 of 3 Configurations; Page 1', async () => { + await page.waitForSelector('text=Showing 1-3 of 3 Configurations'); + await page.click('[aria-label="expands filter group for Type filter"]'); + }); step( 'Click [aria-label="Use up and down arrows to move focus over options. Enter to select. Escape to collapse options."] >> text=browser', @@ -69,27 +70,33 @@ journey(`MonitorManagementList`, async ({ page, params }) => { '[aria-label="Use up and down arrows to move focus over options. Enter to select. Escape to collapse options."] >> text=browser' ); await page.click('[aria-label="Apply the selected filters for Type"]'); - expect(page.url()).toBe( - 'http://localhost:5620/app/synthetics/monitors?monitorType=%5B%22browser%22%5D' - ); + expect(page.url()).toBe(`${pageBaseUrl}?monitorType=%5B%22browser%22%5D`); await page.click('[placeholder="Search by name, url, host, tag, project or location"]'); await Promise.all([ page.waitForNavigation({ - url: 'http://localhost:5620/app/synthetics/monitors?monitorType=%5B%22browser%22%5D&query=3', + url: `${pageBaseUrl}?monitorType=%5B%22browser%22%5D&query=3`, }), page.fill('[placeholder="Search by name, url, host, tag, project or location"]', '3'), ]); await page.click('text=1-1'); - await page.click( - 'text=Showing 1-1 of 1 ConfigurationSortingThis table contains 1 rows out of 1 rows; Page 1 ' - ); + await page.waitForSelector('text=Showing 1-1 of 1 Configuration'); } ); step('when no results appears', async () => { - await page.click('[placeholder="Search by name, url, host, tag, project or location"]'); - await page.fill('[placeholder="Search by name, url, host, tag, project or location"]', '5553'); + await searchBarInput.click(); + await searchBarInput.fill('5553'); + + await page.waitForSelector('text=0-0'); + + // Clear search + await searchBarInput.press('Escape'); + await page.waitForSelector('text=1-3'); + }); - await page.click('text=0-0'); + step('Shows monitor summary', async () => { + const statSummaryPanel = page.locator(byTestId('syntheticsManagementSummaryStats')); // Summary stat elements + await expect(statSummaryPanel.locator('text=3').count()).resolves.toEqual(1); // Configurations + await expect(statSummaryPanel.locator('text=0').count()).resolves.toEqual(1); // Disabled }); }); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/location_status_badges.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/location_status_badges.tsx index a61daea24e52c..f0957fb5cdfa6 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/location_status_badges.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/location_status_badges.tsx @@ -16,16 +16,18 @@ import { EuiToolTip, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { EXPAND_LOCATIONS_LABEL } from '../../monitors_page/management/monitor_list_table/labels'; import { LocationsStatus } from '../../../hooks'; +import { useMonitorDetailLocator } from '../../../hooks/use_monitor_detail_locator'; const DEFAULT_DISPLAY_COUNT = 3; export const LocationStatusBadges = ({ loading, locations, + configId, }: { locations: LocationsStatus; loading: boolean; + configId: string; }) => { const [toDisplay, setToDisplay] = useState(DEFAULT_DISPLAY_COUNT); @@ -36,15 +38,15 @@ export const LocationStatusBadges = ({ const locationsToDisplay = locations.slice(0, toDisplay); return ( - + {locationsToDisplay.map((loc) => ( - - } - color="hollow" - > - {loc.label} - + + ))} {locations.length > toDisplay && ( @@ -71,7 +73,7 @@ export const LocationStatusBadges = ({ )} {toDisplay > DEFAULT_DISPLAY_COUNT && ( - + { + const monitorDetailLinkUrl = useMonitorDetailLocator({ + configId, + locationId, + }); + + return ( + } + color="hollow" + iconOnClickAriaLabel={CLICK_LOCATION_LABEL} + iconOnClick={() => { + // Empty + }} + href={monitorDetailLinkUrl ?? '/'} + > + {locationLabel} + + ); +}; + +const EXPAND_LOCATIONS_LABEL = i18n.translate( + 'xpack.synthetics.management.monitorList.locations.expand', + { + defaultMessage: 'Click to view remaining locations', + } +); + const COLLAPSE_LOCATIONS_LABEL = i18n.translate( 'xpack.synthetics.management.monitorList.locations.collapse', { defaultMessage: 'Click to collapse locations', } ); + +const CLICK_LOCATION_LABEL = i18n.translate('xpack.synthetics.management.location.clickMessage', { + defaultMessage: 'Click to view details for this location.', +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_details_panel.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_details_panel.tsx index 901dbf21b2d90..2bfd04fa26d57 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_details_panel.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_details_panel.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { EuiLink, EuiText, - EuiBadge, EuiSpacer, EuiDescriptionList, EuiLoadingContent, @@ -19,7 +18,6 @@ import { import { i18n } from '@kbn/i18n'; import { useDispatch } from 'react-redux'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { capitalize } from 'lodash'; import { TagsBadges } from './tag_badges'; import { useFormatTestRunAt } from '../../../utils/monitor_test_result/test_time_formats'; import { PanelWithTitle } from './panel_with_title'; @@ -32,6 +30,7 @@ import { MonitorFields, Ping, } from '../../../../../../common/runtime_types'; +import { MonitorTypeBadge } from './monitor_type_badge'; const TitleLabel = euiStyled(EuiDescriptionListTitle)` width: 40%; @@ -113,11 +112,7 @@ export const MonitorDetailsPanel = ({ {configId} {MONITOR_TYPE_LABEL} - - {monitor?.type === 'browser' - ? capitalize(monitor?.type) - : monitor?.type?.toUpperCase()} - + {FREQUENCY_LABEL} {frequencyStr(monitor[ConfigKey.SCHEDULE])} diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_type_badge.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_type_badge.tsx new file mode 100644 index 0000000000000..5664d30761a96 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_type_badge.tsx @@ -0,0 +1,78 @@ +/* + * 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 React, { MouseEvent, KeyboardEvent } from 'react'; +import { EuiBadge, EuiIcon } from '@elastic/eui'; +import { euiStyled } from '@kbn/kibana-react-plugin/common'; +import { + EncryptedSyntheticsMonitor, + ConfigKey, + FormMonitorType, + DataStream, +} from '../../../../../../common/runtime_types'; + +export function MonitorTypeBadge({ + monitor, + ariaLabel, + onClick, + onKeyPress, +}: { + monitor: EncryptedSyntheticsMonitor; + ariaLabel?: string; + onClick?: (evt: MouseEvent) => void; + onKeyPress?: (evt: KeyboardEvent) => void; +}) { + const badge = ( + + {' '} + {getMonitorTypeBadgeTitle(monitor)} + + ); + + return onClick ? ( +
    + {badge} +
    + ) : ( + badge + ); +} + +function getMonitorTypeBadgeTitle(monitor: EncryptedSyntheticsMonitor) { + switch (monitor[ConfigKey.FORM_MONITOR_TYPE]) { + case FormMonitorType.TCP: + case FormMonitorType.HTTP: + case FormMonitorType.ICMP: + return monitor?.type?.toUpperCase(); + case FormMonitorType.SINGLE: + return 'Page'; + case FormMonitorType.MULTISTEP: + return 'Journey'; + } + + switch (monitor?.type) { + case DataStream.BROWSER: + return 'Journey'; + default: + return monitor?.type?.toUpperCase(); + } +} + +function getMonitorTypeBadgeIcon(monitor: EncryptedSyntheticsMonitor) { + return monitor?.type === 'browser' ? 'videoPlayer' : 'online'; +} + +const EuiBadgeStyled = euiStyled(EuiBadge)<{ 'data-is-clickable': boolean }>` + ${({ 'data-is-clickable': dataIsClickable }) => (dataIsClickable ? `cursor: pointer;` : '')} + &&& { + .euiBadge__text { + display: flex; + align-items: center; + gap: 4px; + } + } +`; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/tag_badges.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/tag_badges.tsx index 2ba6ce44a1d73..f92a2a524ff1d 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/tag_badges.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/tag_badges.tsx @@ -69,7 +69,9 @@ export const TagsBadges = ({ tags, onClick }: Props) => { content={ <> {tags.slice(toDisplay, tags.length).map((tag) => ( - {tag} + + {tag} + ))} } @@ -110,7 +112,7 @@ const EXPAND_TAGS_LABEL = i18n.translate('xpack.synthetics.management.monitorLis }); const COLLAPSE_TAGS_LABEL = i18n.translate( - 'xpack.synthetics.management.monitorList.tags.collpase', + 'xpack.synthetics.management.monitorList.tags.collapse', { defaultMessage: 'Click to collapse tags', } diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/locations_status.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/locations_status.tsx index 5834e0cd1039c..0e5101cece27b 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/locations_status.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/locations_status.tsx @@ -18,5 +18,5 @@ export const LocationsStatus = ({ }) => { const { locations, loading } = useStatusByLocation({ configId, monitorLocations }); - return ; + return ; }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/columns.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/columns.tsx index 82faea3770051..08477bd9eb7d9 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/columns.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/columns.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiBadge, EuiBasicTableColumn } from '@elastic/eui'; +import { EuiBasicTableColumn } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; import { useHistory } from 'react-router-dom'; @@ -21,13 +21,13 @@ import { MonitorDetailsLink } from './monitor_details_link'; import { ConfigKey, - DataStream, EncryptedSyntheticsSavedMonitor, OverviewStatusState, ServiceLocations, SyntheticsMonitorSchedule, } from '../../../../../../../common/runtime_types'; +import { MonitorTypeBadge } from '../../../common/components/monitor_type_badge'; import { getFrequencyLabel } from './labels'; import { MonitorEnabled } from './monitor_enabled'; import { MonitorLocations } from './monitor_locations'; @@ -65,6 +65,19 @@ export function useMonitorListColumns({ ), }, + // Only show Project ID column if project monitors are present + ...(status?.projectMonitorsCount ?? 0 > 0 + ? [ + { + align: 'left' as const, + field: ConfigKey.PROJECT_ID as string, + name: i18n.translate('xpack.synthetics.management.monitorList.projectId', { + defaultMessage: 'Project ID', + }), + sortable: true, + }, + ] + : []), { align: 'left' as const, field: ConfigKey.MONITOR_TYPE, @@ -72,8 +85,18 @@ export function useMonitorListColumns({ defaultMessage: 'Type', }), sortable: true, - render: (monitorType: DataStream) => ( - {monitorType === DataStream.BROWSER ? 'Browser' : 'Ping'} + render: (_: string, monitor: EncryptedSyntheticsSavedMonitor) => ( + { + history.push({ + search: `monitorType=${encodeURIComponent( + JSON.stringify([monitor[ConfigKey.MONITOR_TYPE]]) + )}`, + }); + }} + /> ), }, { @@ -110,7 +133,7 @@ export function useMonitorListColumns({ { - history.push({ search: `tags=${JSON.stringify([tag])}` }); + history.push({ search: `tags=${encodeURIComponent(JSON.stringify([tag]))}` }); }} /> ), diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/labels.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/labels.tsx index dc921a0fd9fbd..75660bcf91071 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/labels.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/labels.tsx @@ -34,13 +34,6 @@ export const NO_DATA_MESSAGE = i18n.translate( } ); -export const EXPAND_LOCATIONS_LABEL = i18n.translate( - 'xpack.synthetics.management.monitorList.locations.expand', - { - defaultMessage: 'Click to view remaining locations', - } -); - export const EXPAND_TAGS_LABEL = i18n.translate( 'xpack.synthetics.management.monitorList.tags.expand', { @@ -201,10 +194,6 @@ export const DISABLE_MONITOR_LABEL = i18n.translate( } ); -export const PROJECT = i18n.translate('xpack.synthetics.management.project', { - defaultMessage: 'Project', -}); - export const getMonitorEnabledSuccessLabel = (name: string) => i18n.translate('xpack.synthetics.management.monitorEnabledSuccessMessage', { defaultMessage: 'Monitor {name} enabled successfully.', @@ -222,3 +211,9 @@ export const getMonitorEnabledUpdateFailureMessage = (name: string) => defaultMessage: 'Unable to update monitor {name}.', values: { name }, }); + +export const getFilterForTypeMessage = (typeName: string) => + i18n.translate('xpack.synthetics.management.filter.clickTypeMessage', { + defaultMessage: 'Click to filter records for type {typeName}.', + values: { typeName }, + }); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_details_link.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_details_link.tsx index 9c679004f998f..f255feef4c860 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_details_link.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_details_link.tsx @@ -6,16 +6,14 @@ */ import React from 'react'; -import { EuiLink, EuiIcon } from '@elastic/eui'; +import { EuiLink } from '@elastic/eui'; import { useSelector } from 'react-redux'; import { selectSelectedLocationId } from '../../../../state'; import { ConfigKey, EncryptedSyntheticsSavedMonitor, - SourceType, } from '../../../../../../../common/runtime_types'; -import { useMonitorDetailLocator } from '../../hooks/use_monitor_detail_locator'; -import * as labels from './labels'; +import { useMonitorDetailLocator } from '../../../../hooks/use_monitor_detail_locator'; export const MonitorDetailsLink = ({ monitor }: { monitor: EncryptedSyntheticsSavedMonitor }) => { const lastSelectedLocationId = useSelector(selectSelectedLocationId); @@ -32,23 +30,5 @@ export const MonitorDetailsLink = ({ monitor }: { monitor: EncryptedSyntheticsSa locationId, }); - const isProjectMonitor = monitor[ConfigKey.MONITOR_SOURCE_TYPE] === SourceType.PROJECT; - const projectLabel = isProjectMonitor - ? `${labels.PROJECT}: ${monitor[ConfigKey.PROJECT_ID]}` - : ''; - - return ( - <> - {monitor.name} - {isProjectMonitor ? ( - - ) : null} - - ); + return {monitor.name}; }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_enabled.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_enabled.tsx index 863353eba26b6..e4354a2592168 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_enabled.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_enabled.tsx @@ -68,7 +68,7 @@ export const MonitorEnabled = ({ label={enabled ? labels.DISABLE_MONITOR_LABEL : labels.ENABLE_MONITOR_LABEL} title={enabled ? labels.DISABLE_MONITOR_LABEL : labels.ENABLE_MONITOR_LABEL} data-test-subj="syntheticsIsMonitorEnabled" - isSwitchable={isSwitchable} + data-is-switchable={isSwitchable} onChange={handleEnabledChange} /> )} @@ -76,8 +76,10 @@ export const MonitorEnabled = ({ ); }; -const SwitchWithCursor = euiStyled(EuiSwitch)<{ isSwitchable: boolean }>` +// data-* is the DOM compatible prop format +const SwitchWithCursor = euiStyled(EuiSwitch)<{ 'data-is-switchable': boolean }>` & > button { - cursor: ${({ isSwitchable }) => (isSwitchable ? undefined : 'not-allowed')}; + cursor: ${({ 'data-is-switchable': isSwitchable }) => + isSwitchable ? undefined : 'not-allowed'}; } `; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_locations.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_locations.tsx index cfeb7b916018a..858e57b13d114 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_locations.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_locations.tsx @@ -34,7 +34,9 @@ export const MonitorLocations = ({ locations, monitorId, status }: Props) => { }) .filter(Boolean) as LocationsStatus; - return ; + return ( + + ); }; function getLocationStatusColor( diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_stats/monitor_stats.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_stats/monitor_stats.tsx index 04e90680eb1c0..853a627803fa1 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_stats/monitor_stats.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_stats/monitor_stats.tsx @@ -34,6 +34,7 @@ export const MonitorStats = ({ status }: { status: OverviewStatusState | null }) <> (); const missingLabelLocations = new Set(); + let projectMonitorsCount = 0; this.monitors.forEach((monitor) => { const attrs = monitor.attributes; + projectMonitorsCount += attrs?.[ConfigKey.MONITOR_SOURCE_TYPE] === SourceType.PROJECT ? 1 : 0; allIds.push(attrs[ConfigKey.MONITOR_QUERY_ID]); + if (attrs[ConfigKey.ENABLED] === true) { enabledIds.push(attrs[ConfigKey.MONITOR_QUERY_ID]); } @@ -123,13 +127,13 @@ export class StatusRuleExecutor { missingLabelLocations ); - return { enabledIds, listOfLocations, allIds }; + return { enabledIds, listOfLocations, allIds, projectMonitorsCount }; } async getDownChecks( prevDownConfigs: OverviewStatus['downConfigs'] = {} ): Promise { - const { listOfLocations, allIds, enabledIds } = await this.getMonitors(); + const { listOfLocations, allIds, enabledIds, projectMonitorsCount } = await this.getMonitors(); if (enabledIds.length > 0) { const currentStatus = await queryMonitorStatus( @@ -158,6 +162,7 @@ export class StatusRuleExecutor { staleDownConfigs, allMonitorsCount: allIds.length, disabledMonitorsCount: allIds.length - enabledIds.length, + projectMonitorsCount, }; } const staleDownConfigs = this.markDeletedConfigs(prevDownConfigs); @@ -170,6 +175,7 @@ export class StatusRuleExecutor { enabledIds, allMonitorsCount: allIds.length, disabledMonitorsCount: allIds.length, + projectMonitorsCount, }; } diff --git a/x-pack/plugins/synthetics/server/queries/query_monitor_status.ts b/x-pack/plugins/synthetics/server/queries/query_monitor_status.ts index d2af120492597..61a8fb572b2dc 100644 --- a/x-pack/plugins/synthetics/server/queries/query_monitor_status.ts +++ b/x-pack/plugins/synthetics/server/queries/query_monitor_status.ts @@ -18,7 +18,12 @@ export async function queryMonitorStatus( range: { from: string | number; to: string }, ids: string[], monitorLocationsMap?: Record -): Promise> { +): Promise< + Omit< + OverviewStatus, + 'disabledCount' | 'allMonitorsCount' | 'disabledMonitorsCount' | 'projectMonitorsCount' + > +> { const idSize = Math.trunc(DEFAULT_MAX_ES_BUCKET_SIZE / listOfLocations.length || 1); const pageCount = Math.ceil(ids.length / idSize); const promises: Array> = []; diff --git a/x-pack/plugins/synthetics/server/routes/common.ts b/x-pack/plugins/synthetics/server/routes/common.ts index 0e39d2475ab14..da8a6b476ceb0 100644 --- a/x-pack/plugins/synthetics/server/routes/common.ts +++ b/x-pack/plugins/synthetics/server/routes/common.ts @@ -70,7 +70,7 @@ export const getMonitors = ( type: syntheticsMonitorType, perPage, page, - sortField: sortField === 'schedule.keyword' ? 'schedule.number' : sortField, + sortField: parseMappingKey(sortField), sortOrder, searchFields: SEARCH_FIELDS, search: query ? `${query}*` : undefined, @@ -170,3 +170,14 @@ export const isMonitorsQueryFiltered = (monitorQuery: MonitorsQuery) => { !!status?.length ); }; + +function parseMappingKey(key: string | undefined) { + switch (key) { + case 'schedule.keyword': + return 'schedule.number'; + case 'project_id.keyword': + return 'project_id'; + default: + return key; + } +} diff --git a/x-pack/plugins/synthetics/server/routes/status/current_status.ts b/x-pack/plugins/synthetics/server/routes/status/current_status.ts index a9bdba81c95e6..ec5f97a668df3 100644 --- a/x-pack/plugins/synthetics/server/routes/status/current_status.ts +++ b/x-pack/plugins/synthetics/server/routes/status/current_status.ts @@ -17,7 +17,7 @@ import { UMServerLibs } from '../../legacy_uptime/uptime_server'; import { SyntheticsRestApiRouteFactory } from '../../legacy_uptime/routes'; import { UptimeEsClient } from '../../legacy_uptime/lib/lib'; import { SyntheticsMonitorClient } from '../../synthetics_service/synthetics_monitor/synthetics_monitor_client'; -import { ConfigKey, ServiceLocation } from '../../../common/runtime_types'; +import { ConfigKey, ServiceLocation, SourceType } from '../../../common/runtime_types'; import { QuerySchema, MonitorsQuery } from '../common'; /** @@ -46,9 +46,12 @@ export async function getStatus( params: MonitorsQuery ) { const { query } = params; + const enabledIds: string[] = []; let disabledCount = 0; let disabledMonitorsCount = 0; + let projectMonitorsCount = 0; + let maxPeriod = 0; let listOfLocationsSet = new Set(); const monitorLocationMap: Record = {}; @@ -67,6 +70,7 @@ export async function getStatus( ConfigKey.LOCATIONS, ConfigKey.MONITOR_QUERY_ID, ConfigKey.SCHEDULE, + ConfigKey.MONITOR_SOURCE_TYPE, ], }); @@ -88,6 +92,8 @@ export async function getStatus( for (const monitor of allMonitors) { const attrs = monitor.attributes; + projectMonitorsCount += attrs?.[ConfigKey.MONITOR_SOURCE_TYPE] === SourceType.PROJECT ? 1 : 0; + if (attrs[ConfigKey.ENABLED] === false) { disabledCount += attrs[ConfigKey.LOCATIONS].length; disabledMonitorsCount += 1; @@ -131,6 +137,7 @@ export async function getStatus( return { allMonitorsCount: allMonitors.length, disabledMonitorsCount, + projectMonitorsCount, enabledIds, disabledCount, up, From f48451c1d3dcc107ac6108170c0c144ef20f69d4 Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Wed, 18 Jan 2023 14:42:07 +0100 Subject: [PATCH 39/44] [Fleet] fix for install latest GA bug (#149104) ## Summary Closes https://github.com/elastic/kibana/issues/149056 Fixes issue where latest GA version couldn't be installed if there is a newer prerelease version in the registry. The fix works regardless of the beta switch being on or off. Test steps: 1. Open Kibana, Go to Integrations 2. Enable beta integrations (to verify a beta version is available) 3. Select Elastic Defend 4. Install latest GA version (v8.6.1) 5. The install should finish successfully image image ### Checklist - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- x-pack/plugins/fleet/common/services/index.ts | 5 +++++ .../services/package_prerelease.test.ts | 0 .../services/package_prerelease.ts | 2 +- .../package_policy_input_stream.tsx | 2 +- .../sections/epm/screens/detail/index.tsx | 10 ++++++---- .../epm/screens/detail/overview/overview.tsx | 7 +++++-- .../sections/epm/screens/home/index.tsx | 2 +- x-pack/plugins/fleet/public/services/index.ts | 1 - .../server/services/epm/packages/install.ts | 4 +++- .../apis/epm/install_prerelease.ts | 18 +++++++++++++++++- .../endpoint/endpoint-8.7.0-next.zip | Bin 0 -> 1477466 bytes 11 files changed, 39 insertions(+), 12 deletions(-) rename x-pack/plugins/fleet/{public => common}/services/package_prerelease.test.ts (100%) rename x-pack/plugins/fleet/{public => common}/services/package_prerelease.ts (97%) create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/endpoint/endpoint-8.7.0-next.zip diff --git a/x-pack/plugins/fleet/common/services/index.ts b/x-pack/plugins/fleet/common/services/index.ts index 1d75aa34e9239..7b076729f5a4e 100644 --- a/x-pack/plugins/fleet/common/services/index.ts +++ b/x-pack/plugins/fleet/common/services/index.ts @@ -51,3 +51,8 @@ export { } from './datastream_es_name'; export * from './file_storage'; +export { + getPackageReleaseLabel, + isPackagePrerelease, + mapPackageReleaseToIntegrationCardRelease, +} from './package_prerelease'; diff --git a/x-pack/plugins/fleet/public/services/package_prerelease.test.ts b/x-pack/plugins/fleet/common/services/package_prerelease.test.ts similarity index 100% rename from x-pack/plugins/fleet/public/services/package_prerelease.test.ts rename to x-pack/plugins/fleet/common/services/package_prerelease.test.ts diff --git a/x-pack/plugins/fleet/public/services/package_prerelease.ts b/x-pack/plugins/fleet/common/services/package_prerelease.ts similarity index 97% rename from x-pack/plugins/fleet/public/services/package_prerelease.ts rename to x-pack/plugins/fleet/common/services/package_prerelease.ts index 6cda43e20e642..9c980b3c6e48a 100644 --- a/x-pack/plugins/fleet/public/services/package_prerelease.ts +++ b/x-pack/plugins/fleet/common/services/package_prerelease.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { IntegrationCardReleaseLabel, RegistryRelease } from '../../common/types'; +import type { IntegrationCardReleaseLabel, RegistryRelease } from '../types'; export function isPackagePrerelease(version: string): boolean { // derive from semver diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_stream.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_stream.tsx index 814d1b47783f3..585385f1574c9 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_stream.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_stream.tsx @@ -23,7 +23,7 @@ import { useRouteMatch } from 'react-router-dom'; import { useConfig, useGetDataStreams } from '../../../../../../../../hooks'; -import { mapPackageReleaseToIntegrationCardRelease } from '../../../../../../../../services/package_prerelease'; +import { mapPackageReleaseToIntegrationCardRelease } from '../../../../../../../../../common/services'; import type { ExperimentalDataStreamFeature } from '../../../../../../../../../common/types/models/epm'; import type { diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx index b18e0b49d2445..dafe901121c54 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx @@ -25,9 +25,11 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import semverLt from 'semver/functions/lt'; -import { getPackageReleaseLabel } from '../../../../../../services/package_prerelease'; - -import { splitPkgKey } from '../../../../../../../common/services'; +import { + getPackageReleaseLabel, + isPackagePrerelease, + splitPkgKey, +} from '../../../../../../../common/services'; import { HIDDEN_API_REFERENCE_PACKAGES } from '../../../../../../../common/constants'; import { @@ -42,7 +44,7 @@ import { useGetSettings, } from '../../../../hooks'; import { INTEGRATIONS_ROUTING_PATHS } from '../../../../constants'; -import { ExperimentalFeaturesService, isPackagePrerelease } from '../../../../services'; +import { ExperimentalFeaturesService } from '../../../../services'; import { useGetPackageInfoByKey, useLink, diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/overview.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/overview.tsx index 21b3fd0f4f11c..53806c5b4d98c 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/overview.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/overview.tsx @@ -10,10 +10,13 @@ import { EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiLink, EuiButton } import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { isIntegrationPolicyTemplate } from '../../../../../../../../common/services'; +import { + isIntegrationPolicyTemplate, + isPackagePrerelease, +} from '../../../../../../../../common/services'; import { useFleetStatus, useLink, useStartServices } from '../../../../../../../hooks'; -import { isPackagePrerelease, isPackageUnverified } from '../../../../../../../services'; +import { isPackageUnverified } from '../../../../../../../services'; import type { PackageInfo, RegistryPolicyTemplate } from '../../../../../types'; import { Screenshots } from './screenshots'; diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/index.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/index.tsx index ea6e1ad3d0e12..5b19e397a929e 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/index.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/index.tsx @@ -10,7 +10,7 @@ import { Switch, Route } from 'react-router-dom'; import type { CustomIntegration } from '@kbn/custom-integrations-plugin/common'; -import { getPackageReleaseLabel } from '../../../../../../services/package_prerelease'; +import { getPackageReleaseLabel } from '../../../../../../../common/services'; import { installationStatuses } from '../../../../../../../common/constants'; diff --git a/x-pack/plugins/fleet/public/services/index.ts b/x-pack/plugins/fleet/public/services/index.ts index 07a0d68a22c1c..ad5dab5d5868d 100644 --- a/x-pack/plugins/fleet/public/services/index.ts +++ b/x-pack/plugins/fleet/public/services/index.ts @@ -48,5 +48,4 @@ export { pkgKeyFromPackageInfo } from './pkg_key_from_package_info'; export { createExtensionRegistrationCallback } from './ui_extensions'; export { incrementPolicyName } from './increment_policy_name'; export { policyHasFleetServer } from './has_fleet_server'; -export { isPackagePrerelease } from './package_prerelease'; export { generateNewAgentPolicyWithDefaults } from './generate_new_agent_policy'; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/install.ts b/x-pack/plugins/fleet/server/services/epm/packages/install.ts index 7d80c968edd93..e223fa490f6d7 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/install.ts @@ -19,6 +19,8 @@ import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common/constants'; import pRetry from 'p-retry'; +import { isPackagePrerelease } from '../../../../common/services'; + import { FLEET_INSTALL_FORMAT_VERSION } from '../../../constants/fleet_es_assets'; import { generateESIndexPatterns } from '../elasticsearch/template/template'; @@ -302,7 +304,7 @@ async function installPackageFromRegistry({ const [latestPackage, { paths, packageInfo, verificationResult }] = await Promise.all([ Registry.fetchFindLatestPackageOrThrow(pkgName, { ignoreConstraints, - prerelease: true, + prerelease: isPackagePrerelease(pkgVersion), // fetching latest GA version if the package to install is GA, so that it is allowed to install }), Registry.getPackage(pkgName, pkgVersion, { ignoreUnverified: force && !neverIgnoreVerificationError, diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_prerelease.ts b/x-pack/test/fleet_api_integration/apis/epm/install_prerelease.ts index 86e91d6707c5a..b5af4ebadb1cd 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_prerelease.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_prerelease.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; import { skipIfNoDockerRegistry } from '../../helpers'; import { setupFleetAndAgents } from '../agents/services'; @@ -39,5 +39,21 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); }); + + describe('installs GA package that has a prerelease version', async () => { + const pkg = 'endpoint'; + const version = '8.6.1'; + + it('should install the GA package correctly', async function () { + const response = await supertest + .post(`/api/fleet/epm/packages/${pkg}/${version}`) + .set('kbn-xsrf', 'xxxx') + .expect(200); + + expect(response.body.items.find((item: any) => item.id.includes(version))); + + await deletePackage(pkg, version); + }); + }); }); } diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/endpoint/endpoint-8.7.0-next.zip b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/endpoint/endpoint-8.7.0-next.zip new file mode 100644 index 0000000000000000000000000000000000000000..2002c1c8c20026fcdf8107808e181460c97be15c GIT binary patch literal 1477466 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℘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

    >$QDCz_N9rV=l`y3L&#Qc@^f6VQG z>4Z3)!pM$N(wRrte1WryEve>Fy`ERxf2wV{^GEgb>+_h~;kv)05wgzOp1;3i9<}S) z#rLb}Y@S2(x}T$|QP20kMBWtCs&=yz_Hs46rDFXd>|lQ2z#5xU`-f40L8l#`I2G8w zqlIeB4ra-@Uw9tPy%R619B}d~3M!CtkC@xw#Op-R?D%Zzxyq7@B+X$6fKyNCn{prW zHF3V8&^bL$yiFMsYjA?;xbWW&>G&1Rl1iqAR~SWk1|^aa5$db_c!GtXrIsklOZ3r{ zl6)DVwldLdjiS1M4Usk=yjn+M0H{i~`*6nQeGH`(l0DnXb4w+u0qyU4 zAxwevl8ocGEJW$LXW-B5%0ArH?xR<0T;yI>|!cPlx1oY*5cb(`4 z#PjIsa&|F#VCXF6P+vmR$B0mj)&tc>9^wn(9b>+4F3#Xc#=aQgdk9E^QVU`M!s7;O zExTJULb;0+^nz|%gD6H#=cqFbS>}uPghLoEz!Js;#zjl1wbR<$-)|q^9v|->?pszd zJ+Zm0QA4KVEYvBf?dQg)PRra8#+JyqCCFP-bFI^CVP+=qF&x5k(6(%O+_6+T4tRNC z3G=?883$-T%Tbei?0ayZz!{(yT!w0i9pF(_ZFD@7`E|jTOr*#}ds-#|KIf|_1 zeI3;A>WNlP{Owonmp}%QJgUEp$(_ z0dg@wu?W(BZftVXN@t=e#XhKRNw*5P(mDthkq_Jr{H`fw9iXVciz(rQB13>bc2eU2R z;=P*@-{sLW8XxWOE*zq=Pdw zTyof-)%4(M_?J@~Nbj?BU>5&1)J1d_A4%^lQw>RMA#TGEp?0fX#NH>_WW5yS`o`1F zCCi;jZbR$Tvek_go`Crhf6F2+o7 z%{Bs6e8dE*((6vJ=+581ef_riZdo3e5+*Q4!^^XRDWjyBv->;yTuL^)&O&FM%C>}iAYwRyh?nuO? zlv|O2ThA{3JZBddZ^)O@U$D4y@S-og8F30HK*lP&)P13Suu=#{!x*c?R3}eWCjrp2 zZSty7f1MgOX>v5gi$||E%X6f30TtPOOgX`XiRc!Nxnx)w+gq_-A@SXrHEf>80>X#8 ztmCy=u~U)~Qk94Pg7xO68=7Jd-bi>FQQp*H5eOwKT=?irmB~=Y=g=rnVu49?*jwE9 z(TqW>g3uX*X`XJ?1$L*6F`jyZuoTfLz^*6O#8VmLG_nKLcmT4jv~&R}OH&=3+8lkt zsv-UPw+k!mJ=3Xc%Jy1w>8qcrYgloIw%ON|yQ|_6%W57r3BWI_hgcCCpGhmR0^qJ~ zldW&97P!@!YoD&8*ckY$ZT1q8IuA2ATV`XiaT|HU{l&(CUE(ENPU7^drL-9(^Iv`jhe}R$UeFndgkvp2>VR8UNT@0Np;(_?NG1RBj0PTxSj>g7QnaazP{;5SzJeMDw`qXAG&6p#+NK!QR`h_J! zW5??x==Heu%63+uk1s6w89PR9nuW{G$Y}U%EVv=t@ zPB9be-k5Ifp_>or{NsB&dpi!>Q;v8twj(ozrx5G2K`LEiEn+vBWL>CU0?4+sbXL3~ zbT_cm62_G(p?kjV_nlHKPCO=xv!Y5fr43eP(PZ?ZL+$3ycH^M7yMkE0*7@iP<5 zW%xN7Gg^Md6RLa9F=Wl}#1ZQN+TrajMnUwzkJ&!nP&5W6+zc?b93v9Y%U32egqY+Y zFX7|`uKf_)pd$4S9Zs|`0ObNvA1>FV`Qxltb_CaccbcO}@tF*kFupVDwE?F=3Wk`l zdK~-YknnziavHlk^HvBxM1%LJ25GiK2r3MVc$|VgE`@?VzmYQ}QG+g!n?aYg+ze$F zj%Mo~l)Qz3IW0>N(^FG`Zc^PoMky}uOfqEVEK&2COxNBSP0{6a^8F(0?=Q&kUR&H4 z4g}VXro&N72lWJ&2wzbY=9s@?8%udUV;{Y81pNA&EX%gPwjF z)ou5~VL$#%%Z|SwQ+sV=$7|zyZsR&{ITf1Hq;$y14vA%3)t`|${h8X)#w0y=6BDaz z*Q$%fSKTo_0kY09Jx$=c^**b#mei+J!}~(URGO|aXy(tkda|Z>i`hT0{A3!CzDCN9 zKVp_3ooq1aU<=YL91Jks{XwP!20p~CegF>}XAxq^9{h3~LdJ=F>6H!8raCPhU-tmc zl+LD7bksSWK*j_{y=FfOQTw`@Vj!9+g8*a4frWM(+my+LQZ!$((*-xBZFHM4(2s1k zy7|$(cOnI34atmc@-5pIWZ;LE1otV%It+q4yer-F;JO62*Ps#%6~X>7zmc|dJk|k3rxiMzmVvbajY(D`&xX{oU~f3w)IwOI|ARC2#R=J3d_I;$UZI=`?Z9LVJ+O zgxlh8(F-XJuIH&#&s;w;5jxo{1)Y8W{g(F5o_y~<{RPrJ7kk&02%YSWnQrJUk-^2S z$8Zj0EO@Ge5B`kIbo!kk?1ZsPuuwmQ1GY;^bKPpj+U<`haN(3J`wk`sRr1=?PA5W0 z3@n^n7hx;u%ets^jUT%=QKuR9Zljf9st5BMv*SE{m-v~>Hov4TA;k}^^O`KgZR*vV zxUuT)1teiv4{cd`wTG~`yJLFcdk97j@mnfxstPUVM2g_&dgCv!o97%!n~Z@nG0sHw zEP3}*sH|k&T&+!Mjb^b!z?i-|545`Gut>u52-3etr}{Z@QQBC&M4uRQlh>mI zOGXFIc^q=HCQ6KPhf&T~DfvF*xq{PTli`Gk*sJ!(e22%8F=UyUbMchOh*im1?x2pL z=!HD|k~=vMYodar%g?e+CwSXC`?t4^;GlJ|cd+dr-X6Du-Q&jbQM+-pv%P=RY8*Cp z4tLPbm!BL4jpO~@o15i~L2VGTqzQqv`_HZvSbdP9zq!N1RJ`VPitp+|VS?fWy&eQN0e1?zk6aJxy8Tb!gZ`8%CT3iv0>k?Va zMRKrMWqux4fm@_`^EeD*bm{5RL_pT)M6RD@mYKc1>(k?bqN3k?OK7XBktp(Tx4BdPRZVCUKDgoEr7+GwV=mu7n9~&yRFtX{BwOTfIr+X_Bq;=if9&D0-IXAwIhBn$51CDg9hoT^cDq44gqC2E z=it`v_cbwK`(tB!`x&f#9OKkTqzVEBk9#YjP~UIeG+Ia7joahx-R;}MVKg4MV(r0M3);FrA(89px%4QX^NHtaUeFU`Le7g0dF%BvE1`evF4fcjKA2aUb5@ z^S_ivBl)BgJ@A83&qNkB7Upx|XVQKmIZBSGS8OF%ajGzGutq$3Jc(Pq-id zIIvgd-+q-!esc6`FaA7k5f$~HSwH>)>Obdx{DsY|w8y>6o{QeYfQT@DYOo0Tl+~1$ z@R%w$wXGGjs?L`tEZ#5SYNACKYMLP%5of(8iD4dXCK+K_k-ayJ;IypQ7HGY`KV`tR|p zF51nE(31wsroLe6P0uwR&A@G|GlDnwTf{Zvy6z0mBHSju7X~9pH~gdT8{iw~&o6ar z^l4AOcO8?Hf#04}T?lgL4ipK2CS! z#_(xsTiyc_l)2fS^tHK-q9Mi-2I#tMx5s{L@|2yEDch9X-cED}q;f@pt1c295i$n; zZ-9)t$KjNxZ(ia+Be(%r^8|ofCM?E4s6BZmE3<_VL+9-X2Ljk^MKHpZLIrrA z#3vz6qS4*G_m@#HB68H!jJ;0yKJb3y-@f;sd2eBC0%8DVm`?hO@rYGWvG+Z8HH15p zUjytOLuyb>*x*IGcnHY~y=Katm|2QXr7cl>g1;qww1WOUh-iRh<*8JHc_i)TxqXKh zws{Qz2S|c3U0_J*=4;@Lmbm8Nev_)3zLHQp+O81Y3{+^@H6CmYBGgAQs~aIc;O+)j z?plvKY+t)mab1y|ct7&@ZuhshZ!?IH8$ z^eeLMee&DW^a0D`ikj4NHuzk!OEZ~7dIY}^?2^><1esPKw@?`$Tr>#Z-=TH^S2&Wg zKeAnuYtYhP-v^!k?Fc=$ZZnNxh7Xa)#2aD&EDq-n#Te^@%i7Cp_>W`^2ooZ4fQe>( zLvg_Py4+z%+E z!tvI784QuOr1u1@G7-+WU+2$vR6a8U=Qcq5C)^>CTatgn{3g{o60j)rtg@qol+ku@ zhwKr07nzsi%|=UM8$Cq$%=bK~NpP#^_H^sz(4dCGq>tE581XC*siYV2mVl?rB^%;4 z>}&aVyC9&pYck_O=;_Lxgvv}&nIzq)b6e9&9dCpp(}A9s={*UZiO|c7>kvwJ!4MyT zyQ%t!=e0*Ak5_+ff!N%H5=naDu{*uOZV}ogOc+W`=yS??umVtbhf?G_NI-~~m=X}O zkj2zss-4HW_g(Y=iW#Jkg9Honp0N;j!P7;b0mM*kZ^;KV;fr`1KoK**DsnKxTzEPV zDc?+Qm=Ea2s3V(Q@IxK%ZTD}GscNDyWYx9Y3lyh{KH!uZEPItvhR8d|pvt0$ST{Ea z5JJoPUyNw3OFbaP%LbvTG#%P9*Ni#ULm_jfm9ImfPel_H)`pEbTdMJ2|dbEC0s$yan zoc`_-6eb&l?)A+3brjtp$KttMvDa^Z?OotQLIX?>KzunRttf#G4h{|v508$Hj*pLp zLs+J7)eo^SMZqqqj2#IV*#6e4wt$VphGDD_d5Vzi0Obh=Y;GmZ2m9)-IhnK8^9|V8)G8SGQwcUFf!}7Q|Ui|jNo86UUmdhSk zNt_GEPm_Jv%*w)ykM)d|1d0i{egIRXUm;Y}y9;|C>yY*E)0;O>6cBE=O9$1hT!0fY zg1y>dR!$2gk74Nma?t{8be4{T%HBzw5Oicw-SBloo@bd4tH^UR^)<_7k=}_;M_{j- zR_!Hx9Q|1X7%}1`gx4s54`J{g`jooG(f|jQ!Uvm z!8r5y9-CnttqSMQX<4J&*~R5+L3#ng=Ze-WAt+cY!kh)E^pw$z9odovOxfC;2~>%b z*QR)mR8sNV?=hPq95Mz;<_2|IekdSh^RM0pBJvw2UhQzVe$d!E+C{$q2ELDv_V(-h z+xy3jBkyk->`3FSh_9uoX`An0_S8W6xFW)s?c`UIpzm4qz`WB~uNY_i9ZG|H2$f3K zDL5u#R%GEK-%{o=js#tV;lUzPvEICxY#RI@B9_^ypV-Tnro> zFx@ctA>eep{{3Stg{pX1;?3lDvU<81@hiCSpbD7MAL~K$N5cpqP3#p%YIj$($ZrtT zMU`+{OCZu`(Z_EPNn8;p+k7L-D;q-{NYrAnNXj$mKu%&$KS^?)~Pgj7IUbF?7^ zc_L}Vm1qYMyze2`i-A@jB0L@nzr?ryaPh{x6eRor*$Vp}xBCG?55is~rns8$89a;T zuSL8a?``i*T^dGqs+RvM8I>{r$MC7zZ=VJ6Pdp_eRZ1pUMcWKAZ?u@FhH^EZ+$xodQsdw z#Xy3w3OEB#_MV0P3A=P(Q08DpRfB|W)h8GfIZj&p`}*R|hdugv@ZSSO-|fp#JcPGd zP5=Av@k6DC4@@Q6xKRvC{4{c@P&YmRdt|`r5x6pZs1sozlBtfveWgh!E!1VhFX?K* za1X|7Q#lla0HZ^A?KY67LhU%a{)VdDZo-IiLd_LOF#(#FvJ#?N2u9*+xq}n6;v$GBlM4~7GYiBuI4Gv% zRLV*J-mT-x4(aFA4z6T>>lSZ8>%E9^y^cj~bCXGbHaBb@KDBP!COq1zLP~_)K2njI z#Svj8Zf>~4twNg7#IB%C;?TN%wH#2Ct*$WBqM0EPXc2smYpXET@gX~siN?)V2euKT zVB)B)-y%s4Ue?J1r@DpQ1?^BiSG$p zsx#tHzZr3Q+(dagukvs4$8i1tPGGQovG|Pk$j%M03Ip7hk;nv-L5I@}I%p;SE>@Q? z9I-ma0E)#e6kVocd*4IDg9XVpO8HJ2%Q$kyPa6a2Y)2`mGCx_OtX4gwWY(cHOT1z@ zBnzUot+uMyQJexYwmzfHa|H4JKW&Pnd8GnxI)$#irJ{Gj54Y z3i~a5G`f14Ay<$P>$ea<=-AYo#h`Yp8P^fg2+ieYvMci-;s4VO!o`PX?7|w7r*h#N zz#O*1Xk^08i_zAo|FJ1it;t&*V^G*`WAEPlUSecq=afST3L%kbIdaGtR_1i8Ph{RJ zkTTpzT5?2^G%_PWvE_{I%`y?#iQTA3`;65&=Zo#Z!dzJyeZW3$>iC!k(5d+OR8U$* zF2t*#fuWdYSzS0#K@@O2BW<5u3a5rOYe1J9zxmMH7)t$wrf&{%Ist%!6_&}6RuWm^ zG9&q7(e#Z=EEPexGHoiw*#yUxdD`Ug_qFLFGuhD*V|2@uTYAW#p}<#Q>(USzZ$|?S zLmSdv7;mZtnm;RN?I%uUDy&J142_&RY&59HT5s)^4>XtZoV~X5-f&qDgs4}T3T*0LtFEP4GMY$2Ni)mEKL71^zyHJ0%cIjDrd7%EC>_A9 z>GGeA$S=LnV>tf06FP<W9yWZJ zSLzTUW>GerLr}dXD9Ia1fLvq}wkNA6Q8xa*sFbDqu20LoiyiluMiVba2&p0~(ad6l zq~dl=^wi!aS4n`jlO}BXR(!8c{Ku9^&+7L`z zL(!bNb!&7V7dHJeWIa2ya!$VNM_QIV_0a{@-OQGDh;Fwjk6@Y_XV~l;ly_M7@I)&C z8OtP{W~m2Z`Mb+G68P#Fc6LzTtsi4nNWF2m*RXPEnk}M5Ww8tI(ss9bDy+{Q7hZ-O zNmE((=3K5O+Jp2w1BF+sF&jj`rcdG%QXc&yYv|IlE@xiX|w|5WP zZEZO*h06~#Z>mx|7}NveFUq2&(T2O%dGRs>*}uGeb9(XWs($|a^BH)Su~Amdoy}_& z;m#Y5J^#mlZ*zL^x7RKoNd?u|#-LV-Z}%9Cvq@F2F7ZQUQq_w>SN+XN^r7o- z-KhbwI00l4`|PwXp6bRnyu7Fr15tTj|9EzG_D$XU7QE1l5m;uA2vXf&M(E<;XbdZw zCE!Q&Z;-N#glA;iqTWxZnX?2IPf5kfE!wQ4pTrI!av4_z0se^UoF9?k%y0k5F21RT z1~!?&>51g$<_9Wzf<=4D++77~>8)K@VYrCF!Fn=;b-tf!!;p#3Mr@qB52{4RcL;y7-&w%_ z5M7XhkXAz`-GW}3I-vue^tae{E9k3ANN7>{%r~NoRu{TDSqqtx)QB!ZZPH68dmT$s zXR1?Cc;#dbyEDKot@mU%%|^4E53^3*+Hn(Ad|9Q?lc8ku^V}*^>79xmiHVI(+H+K-722%j7*uP=Ki)px z4Qj#8(Q$3Bwe8n@e{ZjL)Y{$g_ZoY*{-Kr$Rj9C*`wCU3sFmfH__2ysMKCHKumlUy zFLnmSKF=81E-sg|6;fdvDDgZSv;{z`BU7A+=0!p0)-ZxoMrwHAI3ua#q0W)3izIun zstHgRM_7((KF*m21maulQdnmPKC52|`>_ocNe)sbfN$GQ3X%wbC6cGlZC^&bf-vdj z$G)^nBQB(AIEt_kZYrJyrPPshWVA}%1kQ(+TQWy4)#y7+y9ttZBz}lj;Mdr9Y>-G2We%JPE?P2DW@Mlv17@txRL{l>>8e_aoa3U) z2)}7(QzZ>ko$YdU6d8%CdX=p|Bf`@6Q;=kKiym^)V^c^VQC;qF2@Q@p8}KfIec@WD zfGBWk*TOMs!0z=k@7mmsn%s^+KB8@0Gh-X^@D-q7CLUm6M^4i*(%yTMng>I^BP`#v z&Lj_XDjJy1pw>qQB}&fQHT60OrY&o;psoh}02}|9QlndxYD*Qub48DBoAg42x+=+{ z!{FB{&Onk8C{4X9<_M^=SfIUo#2xA8cuXlt`7=nY16_3ECcHyx982fp4eAc56`@UN zD^-KQXLKdO`D1ujZs`+qg4f=o(Mz1thL?7)lTttEm9VY=5g3HUqdf>CDLli+ zMOGkD4Gk;de8T9$keL(at;AG8%R|K_G*swWqA_Oa3~sV4jV;aLvw4xN)~81I!sb1%}UTiDuvuz2(~?&ESlLeSmjsQVt{& zRZS7s;8l;j{{65ojUG}bkfm9~f1oL}hMJZ9Pka^lBeKio`a>N_eS~e8Qah_Q6JG)y zh%1}j%rgj)--76dZZBc|7j&%x@EEn+YU)UhGMo);_URyC5)AGFoC8HeN?EnFs~~}M zzGciLY)P|eIZ>pA%7j=|Rs=6b)zLVa@mVRL$`{?n1nu&Os=$hK!(rfb2y;DWt#=z` zeBlsem^{j!fcU_k2!Hf%!Vc@JLGkZ{pzn?Pn)o9R={YN)spA9oq@Suln8g=Gp6c+} z|FiVTC9WI7SET4oxUCOr+xxYh-K*`RlkNSJ-M#wJ{^1{#+UJMA!klR)TJf*q z>e4PpW={$G`_}xHu*8*EZU_qPr6tP00bOKZGLO$TFvB zHFkFQ_74t^j!fp`A2vElj8Zf|8NjS2I1Q5Pus74xGC%iwc6y+q5rQD~FtRjf)V6jaDwW}ikfDA>35WjE4{0P>eeh#>fm;TTo9pd!I~H&pm!E}Atk!30TAX0@F9qI-gaP{+Ncw`Q3}aSdw+do@mCAN9B2_R> zsYxjh2~PVUFT!tCWi$GlSP;r{Mtx0sAejJbbazvf>C&p&bw<#5#elIUs5viu&o|Qw zjQXMq$*IU_k&{qEu9Y+Diq|$o$`hgwo$sYi;OrIsUI~(A(F~Sx0jRL70?iBa4A{qW zvkbE@;EG-uL|V`gh0csL!3t7Aq9%Z?#=JCqB$@i&Edt7P@tLwr#EcPQF@4Y#*U(GD(HV)70$)>UY=h;Hy|xD+Y0oMPBA%V8ufzh?6pEWsGkKwH zQh)05CM?O&j70>b9r{+QqYC|brblO30JfchCwR!@pjf7l5Fnu&4V{t0^ z#n&$IuRqHs4Q-;($GR(wPymTVt?OT_@y^pt!eDji9)D1+ymgh+96Y*vj* zCSP*VWUF-aX1vWfX#!}fJFj-q2Aj_Tkl! zO9o*W^krBBu(Qf`*PEBxFjC}Q@xGkP3CZnH?rJ+CAt45vAqIHOvObyb@r%S4LDvq0 z5&WKEuB2aME{gNmh*y3i;h_As8LlN%XM6!rnfW~>a^=#11>)eDB!aa;(f~?s2z-LE zB$!$@k?*$SeXV(?&pem^Q!`tsVJzc_9o}lEBWkL>J54~zc$4+%%yA8nuiGpusm(j^ zrApioys{h9%IPguF!iR`h~)0j2a!G?V=luTEFc0=oe^;yBbVbH_=CDoWb5M8FpeI* z!nju^J=LnKF(*twU>az~S?g+Vi!2vNw zawk{hBjXa_OXI*j0w``Qq z;8Ox;a6^e33+{il6yf?(dBvNE`HL>Ae3d7L3GbJ3Vp z`T+U%4DRMj+_6ljT*K4clsH4KP}m^{(QnW~^NiP0ba-v0f%TY<(${j%>TMCp`HdBo z%0nSbORE%86XpMVS1e7y46W!p12#E>Tt+T-6{O{IB4s zS(6^RG#r+&-{JMNF%n8+2rqsv5he(23Cwd<70CuC1O($FInV?aAMinEW1`N9&s9dD zDEgmeTYhWa;TGN`;F=>6rGWk;=0`ef0RCBd*@dKVQKG)o5CFx*A75O&{FC`EudSPi zL5V7liB}=!SE!A_Krnf(ZW5>u!(H3Qa7+0;h-eaB3Tvy9DR)@3$vN^_&(|IMq`ABv z%L+R7<<+$@C9LHomNdui&`qC`5m((oC0gRBGyRH*kv$2 zaV2FQ1^sazxqPY1XN)I_`jZ4*Um_QqamLO(wP+=~TX*YQck3(ZZ-K1CRC5eA9KxK8 zd!VW`!aZ|8Ll_ol^A9I02M*`MEyaebV;Wc?LPxcRDbbR}H-ahxzddFrd6F%79bG=m+{#E17GC(*Ose8S@Pj%LrE9XveQ$~tro`1gKoV8%&9;s4O%3^ zL%?qM-ZT$RM2zv7)j>JkZye=KEf`^8i>k~QOx#Yjlz0gPT_VXz(GXN^792A31l0Y* zx2Lq``7YVaVvyFKu9!$8RKa|rf}#}Arz$E+fqkmNLMJUwyiL`@;!=iI!eNIRYz>+FC(@9STC9?}2^WeaLD4WH#9F66L z)Gjo(w}103MLymIQx{p3UF`*fkcIbL-Sx0C*)o$c5mXaAqF=Z)bLNOG#Lby3$P_i# z78&}_BOBsQ-(xmWdUG3}uHE^(Dv!;ZwfklVT_(=5svPddB#9{pl@>B$YBayK?(si< zY{9z6|1|hn_xSf3+dF%XQ>M&VT2{{C1xB^*@n1G2q%0w+C@03aNP*>bkAF9!*$J~5 zb>7kmF6$ouQSU@cyR*Gh;MzwMIXbatLbH|I6V07!=fP`R8Yy0mbh<+u33qTF_)IHz zLwGc0Xf7b@cZJHQ;=Po%Hg3#7J{>>x`_d=30grXgDy9XTmCh0Dwx01@*E zpcnivAA00exhSlGM1Dc&R{bhs>dPqF)1x?eVU?tb%rS?Ct1tXLV z$(xa^7$Y1!o28pPj_~mCekD-9Avqx-4>i#J2mxLRASW+IH%49?M(izv>9`8tskmyg zR#R~>aT`BaDu?)$s|mA3QG`{~YGZ9w zfr1@$^aM5OUq$+dCJsg0wI?(d0%QPrw$0oT{A63K2UK* zzHZ+TR^9s!cSIU;;Ij8>!N+?a>H&Ol36~ zx9;&AI+&t*4y*|`ibc05`M@PZ-x|0QIPQm^1|K1?hWP4z*aji8XvD|I{C|!B$8dNl zutAPFszOSNxiw9!W~mEIlac=Dc?a)s z+?DCs1i$rqwAOmG*45j0msjU!&9|>#Urj5{a`*RVlmeXF*?P2=AqnS6S&!DTUAnB~ zwapSJIa%YAR9!>P52FYz<5hOEB_M|;OQNtS!&=}_tazKPaw12w&=>NyZ>i!l#w^(^ zulu0(_8E@WGL>6dMY|Lwl^W~|8jZ3JGSO7!Oe*@vE3MM-NKQNZe73zAbFi)QJg!K& z62cN4J5ftn^@YkT%^K7E?{x3}WCQv;5UjSS5$%?Z7Fg*jC48ekA@Hudgjd>@;u^4Q zmZh=RvWsi|Cac|~i#QY()X|Z4q$rjTLcv7iKer6+LDmaejX7;A=2Uy_dOO8Y&ZE|! znU=b&HU>xna;Aj<@nJ1c#}VVUHkP)D@J{7k6_i$`r=tM&fU~IpawpQrJlocqmKV0I zuv}jDH>g7}2cAq=IC-}03(G(L{ zOZm?{M7t@x$-RZf9s5Yrk;EhKz^3Eh(Y`N*hvddf6|o~Bae}k7)iqUd3$u}-HUY1r ziD3QiCw8Nt$dk9w!e{HQq|b`$!u<8d-A}L*iPsH%a-*c*MBnsTuryW(9xV-Fi-nII ze1mAzUzGSO0{>YE6RFa30xg!$Kg!tB8Ot3P4JpM7=ME5!7c zc0n$R(mvr0rbNT7{IsYtA2Tmdu4mREIlFPh1O;^@m|*cU#B}MzyIla^C6&?a;5$;~A&_ zUjN9kYJa>qeRYZ#-G;3Y?rZthpG49^P$O$F4(Y@8e#bVdCB0**2dRSwUt^g+JF>EJ z&kfCCp+&-D=?${%V4^3t7zJJ)`bjV;7Dd-&)EWW;k6LVTgV^V5xU`jS5L$0J@iL6q^&vm>4a$W}~(3ml- zjnBFTJr8#sVW}p{Yd!=S*DN2dyl4ES-8hH7q!v^_avu^3baj=C;?#G?te;VmWiTxf zoHo|bOH-zZSn3jiFk;gA7pM?})P8>v#dX1yaI;_%& zGtl^F>f_hKq~(yNCi0`HP>3E!a}%UO^knHV4c?O_M+0PvOscs~R&-U0rHotIdLgnb za}kv@bxJ4RdJ_415_wgvj=R_7>vLY{^(1o5BbruEV%6dlSG}t9hC0r<2;CLp14?bif(ha!zowcmBgLir>IQ$@C;$O@6XF2)NItpqP2ot`{H%^+0}2x{%B}X%uQ8`KI8=;nxHh3tb^) zeG&4=NG|Gxt4Lb6klPv=(}MNaCN?4;pLjdiWdR)d9Smn3@(k~2Ni$>lj?JFHSKM_p z;c01#O1!E*CSR9#WkPcF3*b|ImHLe=-0)N2H~dqrgI8PrueDnj$&CX7)S9GuC!>1J z)&OdULD#Tn31FiA2dH2$`ke(p`!!Dh@4V$iN?VYFcK(<$hQOLkx#il)|(N+Swu^wp{wG!O_$>{WR?l1mvkvtAon3r@geR|0<=AIHz(7ui~0=z5jB< zC6JWy{n_aoMoUg5d&xU<$p>b4^GDN5+=*r*&dSKjgbh5Rbk){W+b(Me<21B~A6u#+LCln3xgokeJysiV>{YY26+nuqb55!zA0gN#)ek6du> zG;`yJaP|V+>_uBjliJtFAkh)P%AYhB-@MQA0p|_;cy!P_$ZCl2f)5Lvb!n9Oeb^g) z^!N^M1SLbyNrw(?q1jVw3s7(Az>h6dmf>b^@yjSuse2|)2?Vd&2kO5C7RCxUhO45Z%+ z9&+zTPMW5u5q^+6lrOwYrWd&t3y42D@*B6?LA$o^2m7_XMiA8e+k+eY?Rclr+HEwB z4ymi~&qRT;Ql_09Ng8!IgA3u+5{rFPd1eeS-)QoRm!aDOya=U%$F~effG? z)ZYc@F^ewut7L(2>e-$gEgQ@au`Re z!ufM@ACzldT)q~h7a)ADXe|S)sAnvN3@k{c)QP55$nY&-N^(Mr4K(vp06@k~shD-7 z;vCc`-uD)$`doC1rYJ)jx|dE|FmN0@pwWHa?Fei6CW!|re-!t;WLj5!yjj*2C z*b&_F|7Y(_liSF$bix0<3O82Uqm(9q04IrjmR3!XR0J!+(R#1z`rSwYr`_3Kw`hdyd&d`8Y`9dV<@H?G*=JOrZcCH7rG>`;O=k>=b z-CY4V0pLS=7mtT%6~LXnzVRC)kz1zEw%vtTUU*^`+U5aA80{;wx!p(AOiQY_W4>z` z%mrKwAr|lS;LsgbkK=i~HrQ2>k94a;tSCl#`R>qrUD@8GlVUi&Q*Gq;y<>KdMdBxV zX}yq|w>IS7o6-$3P8eT#$;WL*C3fw2@ff7{&<94j2uFvUy(z@Q<<9?C*Z=njkal`yZH5W8eMZBUFlRR~=?7vm_wkjaEG!cXESJ-?G) zO{@$R0$Jj-CzwTO9T1+Cl&`5C9aHZI$W(tB>5C|07$;#9#lL)9x`1bn!G5;fLGHd7E{ zA8#Aob|=<*G&k)Z(^v2JUKlA4#2IOz*z#|1cCWzEeE((${0oiHk_^?UCnGnP^Tut6 zQsy$VUd40Wcy7X@O2z_sXhaBI zgQz)rWIhlTFgS9y*C~ms3R@!g{=^IiE0r>QeM&ek)4EsWcSf|zwV(7t^@00eI06N z3r=GWA;C9os)!U-Fi+Y!#AFCFJdGKMTpPD5dlx9>#eCrfhMpu&4(iX?5Lz?Tf!o93 z7|?d8BJvOl#5)=M58whpYy@gF>R1NtX9g^?Xv0< zW)$pxyH)QE>nN8jXtp(mRq#I&rxazz8p4xp4Eqg$9q988Kai-E4j8`Z4R58zy<^AV z8{;m&rlY7ELVX)p4lQ#W-2YE6fW<48}?2&N9GoS6d4v)nN*$jXJAB(Hp{HJ9CraXft&TE%iF?lnQO}LX>*2NRoJOc z01O=s@%I7tP}#547iM?>qTcB-a%uR zhJeL%`Z`S@Gqq)tmB9Vg`6P0c7_8PDf010J$ixz1^_;4HM2H~l4HVRNAK_=^a)N`3 zUO_me5%AU`Nv1RJos7;sso~```>T6I*Oax6>(UACz-BT}_Zeg1HvNc~o_j^!3#e(+ zyfnscY#@BzOs3e~r{BUy=sQO{FQT)3;0j~_<9|~eA#(d^XQqT=m$6f(8=Emrnqp!f zoO#r|uM_d39{c-5l_8e)$;Bc<&E*K?NdTtQY>h8ZoA(2TGS)-h#_o}u3)`$^GrtkAhCRZBai z&1z{A*i4(-d)3X?Z(f%+clYocBmam4?Ns-6c3;2QEup7~N(6`;Zj!dL8dZOYke*X9 zv>VnaLpCb`ZMGpmvaOG3LIb$dI8dGSd>;K&?nX-X^E*`$A|VdN0(7<_Vxoe@XM#r7 z;sY^;;{o6WSx}77g1FKCc8s35RH>8>BZK0%n8q@tLIml{Sll3IS8If~xg5g`r|&^* zp2_?Y5}SAz^cVES$(5T~??sq?ik+n$O}9tmGrdo6H8Krd<<45#_>2_pl9KE5F36nn zb8Wa84+gn-(F9oC5Dk}O7lTCfQK=uaO3haDVeUK+^L}w_7Ia9)-D1X?y%q?EFEg46 znaj-lYK5w!@9~BGVA2&PW;q?J>Lwf65D^DA!I*j7`sG^KM85`$?cVS7=|Y8EF#-%I zrbq{6VL>R!#N%mS1|?yG*Fq&KFu(5(=HZZO8wh)14DZ?u3+Et2*)7mb5ou-Gh<4Gb zLFhE~J4g|P>=JiVzYXCCr>dx~o#2MfWpUY3lA0+R2WwV_^L3gtm{pmTCgAF^Ky6O` zhy!RKrl$fOD9G+^!)Jyf070taLdIDC{-%+au->~{HVPZ4l3KBeQKpmAaoIISMng}e zMNWb-TlBfT>oro!a*}5;xrO%`=n_}c#0j9^u@ox$dd-e}IHZ-7nkieko6&cqH>ya^ zbPA@`Ti}5s|4g*FGgB*q7J~&(nZLptFN7l2SDh5HbW%t= zq_NZ$r+EBwy1Z9v0PX!%ZJ8v0LQ?2VLn2Fcr|sq-7(z^Xhrys9u+S~&EpdsUZS%U$ zq{1n;X#I+Pqf|&mUPt*oLR3_nc1<`A;e%)F7-;*jOdWF;x#Vpm=2P3FNKs#(^gUP; zg6U5PBp>37y%+CM-Xq%1z###${Rl zJ?=?o6YJY^jOXLa%k#_nhqJ6Aa?)XaZ=!O-I#(joN6$YJqq?5Ss;tFT;|W{65}hJ- zjQb}loVtA!+Sil$Fe!@Zq((J0miUhv-M%t`ZTkt}a*vTkK|Vrd3**d>Z0=67iy}e4 zRo6u{GbO008>vsq-l>7;ZkTtc--wb0)pP}Rnw~R$>LBTGxd|u1%u+UWuGtErnJBb& ziio-+LjqkOq0jdFP<@$6EhRaN0RZvN%wrPAOZKK{n(2yWVFq!^3TX9UOA@XU{}GPC zc#qR84xt~ghoiZXF=9zmuJYUFl?P%O^(uZ;lU1wu?ap#1p4$hJa_?8Y9kq0{o}R^f zJ5IRgsrqW_MV}%WR!$x`s^fZC?3Sizs|#;)x&;2lT|Lr_s@qbz)cKcoogVE-c8zh- z&lOA{50ZI3Uz4mkgGTPmzOE(?hQXM9d&X8<3+!EfIX{uikO&M|r+qU(^LWRTU1Jr5 zlm-g^3sie}#8r4&0^r)IEoCOi)F<~%EHf8K zU%eE&2P%YT1=r#JC*AAu)0F^(Zf$;AYGFRioFAg;fw^C3>Ei5v)ND?bC|Q&~3zF^( zWt@pT>!O+;IE&;k^?)mjG^Oc+E8Hz_mG^clsA+q>T{UuS{;TPiSIrOr4}+R- zz<&sM3k&=OZsI`-$5g9h_;3({N3No(jYLWhC5^_6ad_=}zcJ7)`+&XRHVM2%Ns9j@ z3}fR4$wnKadq4z^N{CP5JI(uz%}RB9qf*_#AWbIAl>lu*EYuPX2t_z04v3G->>rrq z&z0uxo61&m+uz&Vtn!Cev$3s+l6_yUq&@8%6)+FC6^&7yYj#9adEW3 zMbFR_!MX0p^lFWpF?f#r*QbYxMAR3&?rS#8{?Gq0n4S13EQVErZEcbB)`V8q*dRJ5 zsC*0ZMB<6bVKm9s$vl?Hs4Bwaq!T70>?#bdi&O>F2fk8JG)ng*O;qyphT|K6kL%g{ zJy!g*qRsE-;%zgQR3_wJ`DV--XDDR009Y>bBZ<9n36;%~o0(<%8qT6>GR!ROi^ zpzlDt0R6TE*dFYg(`cZDp}%lpdq;+AAeSx&`*!z@FtVJ%c)ix6sq-#<~7n#X|*osx#h?4uQoamy#sjJ$&xz+lk0 zLHd$JS(Uys_7yYG7RmT0kPwA35_LMW(~jnuwSAi{Lo%299rR1)B|%A03zR0J_yDF_ z_$?xlAuoCeIsh0Ef-=Z0Y6s)Rf-w_TI_^KB(+nWhXD@Y%^Ud_${BZFbnyQH2BC$CD z#{)$@AEuP5hNm!}tb97Af6EcE-f2OODuJ`QLh&qvb8EcVI-`O!ukXx=-CH-dsLfm* zs|&{>v9Q33LRCbG3g+oK=}A~?cyoKJ`g-g2_AY9dwimiPla`8G%3}}n{w81gEQfWj z6;czV42J_+AaEQdyElv!tHm=?tak_}>K!YvMy1QlI~CzyE%9y7g~QADbt?KW+Tw>f`b8!Q01wdwaC~XT6Om*6|-> zHeJxH(+=`ujn3y&o~NE&T~|rWJi|G(oH$)LMHs3k3@2cljnVgPFJ)MSGiSI!@jIhV z7#+@5!BD}F%>UWec@{|vNKpz@RC1AO?Wp3oVCgI%K0@`#E>io}%f}~&2bbluU{q?9 z0GK>BbIfp>$%Pke6X^k+H75qlWf^F<)7!aOGm zgNcW3j&d^pkCI!270#Y-!H|0{67 z;JCP`bDeyn*yR;zwkNrCbhJ$8BMHIDSanWEaH0rH+c8oGJ_P6l0sjINc4~&9vu=$# zHxeG-@!_E3#0+D%5;rZN-5pAVXu&vrT;EWe@k7P8CvAZv!=jQQ{{WFQRLF^n4R}vl zH3{;2kAP2F`zj>93W-N^Dko9Oj}RlDw00fME}AFmVPg8rLQJucpn1gWpv#H+e%(Yq zqT7<9M9krDFyh}sn8=I(HGpmhM1}oFzd0VIVqz}qZcuB3fAt4SZ;O$+-2z7@N6++o z6#sVBKcM)xYhQ`~mH3}3{w<~afa2e-eI@?UR#=DDwd}}Q{6}QG@(?hZeT(j+(p*c8 zns5p%Dg4!vicec8HY-7|B1{p8%I*|>EQ{0dRBi*alXTvLvD($qAXLYmu9KtGMP?o7 z9mpr+;7TX!Q6r76P4BC9NiCO7U?vTirebmluK4CfPwDvT`0}G<6C9qOo}Sc9Ho?2g z=vMx#-^MydJ6x=I% zua0|?LngH1?BF6aJqkXfV`>_PeNMdh2;IvuK?ZC%lpvHZw3ljzK8VGIs+%0yoYP=e zvtcHHycv0$07L?!`Qn>rr&cd4wdz-9pxWzV2b5$SwGhM<^~^1cNAGQJ`E>wP?&H+Xjdf@~B`Gmx*%an>?8tyo1>1FR6?Mf7Ym1OEh=Ay{UX1dIE zP4$wP4L=}8?R?9bge`N16d#}&gBR)d>1i)cQT7dLM#W)A{yauX5!9bXi~gxeGfz;I z0s$u>-GhDdU)9n}NGo{YKWG}OfFZNc7_!a!eTxV`lfLG-@#=2d{3{k~I3p<9$-tG6 znD7Mw7&OeDImyY%2ucf3{;M046CA!7l5ZHG_aO^YB*Bczoub^uDJy*KVfEa|t^Lo7GX!tw;pnDnPpAndd=%oP<2GdD4dy;ZZ4 z9uaXg%o~%tdMCD*n)l-BE6;}(4rp)eFEhZX9Yo|!hV5oo zltT9V172+NMr7}U2k5>FO|j6)rSdSNz8b}UUT)SH+{M^!ZZ7_HYmwlIU_gI7(dfOXdGnch~+NZF|T4LXS~MCX+ys1;EB743k6k@eINMS z%@{RKXd;0^=BFVTFc2>8g9n7unDK1RzMcig0@Se5mrVnKMTb zr?CRh(>KLxz6h|Ep)q#+@?*bQ1_eHvoZy*;Mtq9}+I)_im__ieVEZ#+6336|`vJ>~ zt!xF77r)qxgXG1xG_C(Zs%V|U@mJt@4me(HgIAzEo#-#KRyAArfw%=le>z4-Tu&g?K| zAL~4^Dzx4YuPZ>8Mnr$}R0zBE5^nwBJ+MTF z!|p4O9j-e*(t$?!hiIPsiT>$E=M_Pl;O+NAq6BgR-sm{H#cd765BMweUu&zQtmkC( zCFPu7R2vAR3i<8p_ht$nq=jSjDMZ3DG*2DW57+Y2yStbQEUmN4g$abo@<0YQ_%Vv4 zH_*I&#Hh;L(Z9$gR!d1nu5-J;ZtPkOmTAkGA|n>mmw6b?G}oKK#v>Ck#DbfQ>)sP= zJQ`>cKe7XQL$osQI2NF>EW=4L-c2jF2jo)PUlvG6kAMV6mhJ!wM7c811iS3%+H*h| z3l8Z3e`Q~H%i=Jl(IDu+#{vI^8i13QEJ@gj!x20if}e$-Fs%Ka9+U7x@g*9}!f@uk zvo6Kq4&dtPm7FK+HmT?yLxyRaq**Zmy=d*z5r8nd@z1mZ>;dxaG^leQse$nwk;Ek9 ztZ^4#tNlBP{@syR@m|QXUs85GAk9D?SAp2{Z*0mpustu!-T``nH9wOI*%`_%i?bcI zVSM8aDH}xSrNmxq49JjVxYw~6B<*jw4Gj4%#&Pn!px>JyST`4v+vLzQeRhI}h2HHQ zAQtn)?*@&oE?OOsNZXypAbC(w5;C!=KIo!1LdMd{WLSCSI-@pxp+LcX2CtkZynb9M zNf-)F!Uwg6#%LeRZ2&fE>D_U*n|sx^psO}QzP-7Z9**Btb=$Xc}c>u}!*BKiN&HJ+NXcv8hY6I@0uw=(Pz7>Jq+w#*4K7PFSn@ikdV;%?7Q~&$&mU^+3R~%s+MqftEJ5fr14r-zlR%{x2tZ~%KqXP#`FrGu zukPXcvo-;m0O|TQaKzN@Ym|K;Jdg07ObQU~_j+Rp1YB`@&%yAfxiiEcsUM)-jTuX( ztPLTYW z=^B|JpM8ALZe4p88QHEe_IPC4_-+luDz6GsKHK!wV8J&5(x2^0qw4ClxLxcYUAn(^ z_RaAXs~lmvO*p9=zvtg#Td>IEU*5~hFd9}QsFujQMp_G9C`9^gkJeFDLC;Aa!TvVu zw(u6FDbNQ2JYXc{z&Ui|j~;wDRYng194meY2!`|y@g;Y3JOxe3YcG5BhPyLYv8`(y zm;E%dKUOop_Fg22#2i}WnDi08^v*BCcRH_eMsjy9w3?@lB;SC`-Szvw44w2RyqFD1 z1432>x09|toj^i|5mX|fmHlvPk>$pycwZ55d?{hrKK=P{LbIXeop(MrME05S`ar-;=W7E+{FFa?^iu(iYTge<*dqS#t7xer$c=8#arEV-`_JI-s^a zh6x2Yx6AjO#z)%1l60Hf(sJS}h$79QZcYZbKj|r-A=Nds#zM*_wV7DhLx-^>zJ<_u zGz^7+JHkf_U71B%PLNHBbmMDSEIxvTl^I6^&Lcx;fW`ku5UagRJqyPh8Zil|5z0Hf z-ne@M#Z0TyR1Uf17K(@QX6S?tor4 zy6>WRjco>@=b-{nsq|2?q{Rp)AdOFN8wg*t8%PJ$SqtGb2T&i!&3opPu3>YoD!PqQ ze>B{vtd%{g^zshfoB%yNp?Fhe@)5!`dg}XjZ~W+~Ud&d7l*C?hOxC8HyLiskbIOTx zTO%Bf4SZfl|0yJ&v^ywuMlHC*k-=5OQp=GO7VD7rziQfPB|NOrr+FDT0 zk%!CEL|!sR=z}C^@H99>vyEyzT!;~;qZ5K@V>ApQiAFEcUZ}R9EcDhh0GrCEE>E8DxhNFVK!g z)nIAy!uQZp=1!?9alpQ=+ZPyg5au?>p= zJ%=RwhOWhw97g8XndE85&B~AGt@7ft6O}&x$q82FmicGq4ENj!#TPAe-KIs*Cg~pQ zBw)S>MB8%kTExpMe$$a|A=fYpn>5%~H)qN{pjwFb+qjbOz2e@%?FTiY7dV4anc$67 zURBla*!bimi1#w-9I9@;o>%(2Zl+ZM(42T2Q^?tnU1DEX1wcg>07bTYRRH92)KvkH z@WRxKNkeK?00e+3!K7Q&*cMV_8{ti>>JNoCFbxPGHyv% zQWz&BOD?I^tdc;{NMw}+x=I3N5W(|SNubyS8{=Oj2{gjI-JHp|z{<@+ObRU%%aFM& z3wAJZL0`YN;ABL`cmI1;7n~(0&nN4mr`tQJ(aNu)Xe3Iy-&PW6bnf3#66nl@CFwRd zR(a;M0g-u_ypf4v^VD$0_ml)0IgUg!;VKFAYfS>3er~HI(62KIG;(U+dlG1Ju}Rkc zL#rgKBv3In`JY*!<;)CwjwDcYg}g6!TRU^Old?qfPLFm3L0jn^M!AqdhxZMWOFk`k zF3YG_KOa=547<6rThMYbFkU`o=$)#8z$swOczMduPUvoqRj(qUC@P8;AV~p68qC`& z5{j+)3UTm~Qg<1HYPvJvdCCi>B%Dx~7`~e7nTUOuB6#?Ui3TD6X}XIsTJImvzpu$E=hP^ zvO`sl@CMn=vG&rRw%P3^xE%orSFV8RQAC{G=lg{ir zm8}z&yOObx7$SYtWzAo7#JF;KC2K`6r5IKriFW(wNKt1E|4bn^5i}TI#*udW%5r_U zCjcQhP!~Wo03D>hK%hd5V*$h$QB}=cyJ*D?IJ!owHGn^F=4{7s??Hn`$5a5H=%*uY zj~ewLg5BshdYCxuRVmNbQ-}K03D8q0k9iN#G&P?|^G%AGV}5F;gcS0D)0l*?f4J;Nb2bO!G zOY$A9TQYZXn24rEVOx2P*nys!H{rI>0(g9j7NT&hNCQHt$d8SIDO8JSDj=?r7F-_c1L#MmlM_S$?~H&}yLpOn`1( zAbB_kk+l^ACUa~TEqPp+1?-aA`P*?voQr_|1@h{h*Bm_cN9+{Rzi&4^^o~Kh9`6CD zTylu67L`=B^f+FsIrSB4XYmu8teM5H{5RzDNMQy*iR~852{?p<$Y$?&R(2rogHEsR zJLQ1G1i)GV4mVnY3mpIQ^KXBBbNc4sqm`L6Fo&jJ{#30u_4ZHmd0erfu>##wwv4)9 zX(kQO_S!v%w|)eG5;PayXkNUDrjUFO43;3uqOS_V?^zde-EKDKWSSO8GOV zQDmRsGbUVQpX4*9W-LC*WJo(}B3V@ZbQ6R-?VAA{y$(ARRa154BC;sV1%Y8DYvhCs zN0qL8P&ixd;pe2Ps1Pu>Hp>vH8O21uF*427@=lw1H%53^7QjKwitJV}H0~6}9PWSm z6>vkr!|>D96M`V!t<6t)tj~u91$6#ij;M%{b3P$zF121gOyc+e=Bgk0zDF=DOhEE%^IiNGYwYhuwxjA z1DN&DZh1-XN2C65e`Dj};Q@p-@ck#@A{#fbNjFCKs2m@apa-`d`&R5vh4 zlQ^uUZlgm_KuK*zi38%}^8KjWNwV-tbN5YUtGVs(ZEjZiL#x@?+1uS}G+JA`t=4T; zw(ggKTn+mfU8dw}B&A&bOdu|}7P$SVR~H8-XSMS2Z^zkJtgWtsZiMA^dYEMx{hHBQP9Hw<{8i1Nd?9 zhbFwk$f^2(mMO~WqFOV20)p%#fzU5>3fA#szk_QBkJ<4feAh&{MW>z47@(aOLp;RA z_^m6+!oW_|nm4Z|{h{=}eRr=Bz|+1<Fe zsX7(Nab#A)v(1wMWC*-Tg)IEU9Y^gz**oV=7iW?<#Upcpn+r6TDYB$j2HWKh4KAMM zT-Btze}-;m132fQ*s1sF*=Hs*`yw^5dQyAINu2#WMkq&G-4k4W(gG4>HWUk$)O8P$ z!+*Pet3B=ty#){aXN(3ClFYXR;SK8uI%!d1a}c$ep0WXRFa>q}6=w!pz}npr6hUR@ zUr_D8zz)0f&HbD_*U6b!2ZI5ezsjIQew=a_hi^`8^P~|)C5oY{{ zl2Gqj9vhFoeWc{2Qb>&ivBbjO2zrhpOweGkop!g%Nd! ziuyl9-;l(NdD|F1`Y8mRF;bevPmB}^+6p1+vg4*XRbfGRG~h2%IT{#&CL*jVBpNZ) zCx(Gt*P}$@dSw}%29fpmEC$x z@sxNp;P7LPek^X0DQFy900+X2C^!S+hs=eF?{rGdSB`9Nl>>G8;i`6gRKGkwuPvyK z$4~0J%YBM1aFz2EXQi2Qp5i;3Rz;V3%cls1RUI7!T`W5$w$G~^r=fCzCbp>yuM#re zQ4t?CTT+P-9&!Zz2F7In8bA@uf?@y%D!V-PVG8PjlMS%%t(qAL4VW#}D(tF_(Xgb_ zpIF?wYGYJL8zVz&-)Rd>bERSoDHE4^&IU&ISXON=N61b=Onl$FZFJIwsUZJ-vkji~ zQL9BHech@0K$ftA>+M#9Eogm302WumX(gOQ4P~Vo8rBynoFasmOhAdd@thE}$^+bo zLm3%`simbCI>)GO3rB4vcYAZ&zy;2m1QeO6c(LbD?k5)O!o@8eyCpA1&r@C+R=L{A zt|P~Aw^Z3FZEn>nZ}uxY`&--PH#=K@H6<+bE`hm-&jv|3e=5FA>-j({7oXTyS!H2% z?W?S=U_^gq8h{@U8DK=l<8ahMdLOIU@Dql$-_t>|6*Q*z?#SEpUa0MPiTrW^12jLA@Agpq zZ-a?AxUUczQ>%LUDtX_XGss*;Zj*CEuY#^mafo}3JWzGkDEaQ{BI_&^ZMu_o2OZIwrJBpP5flp2K zBQb4Is-nwMEY!_#%xrm|`Wk>3uC;Dkju_7{^RFG@?_@h7WsEAbJk9Jv{dHYJq<=#> z3D?DfX{!&+E&Su#mMHdKXv;2g^)RqLW)6~GY=$UB42x*iSyGh9VS+Qn^oy8xAEkS) z9MiY%n{`%_ukId+f-dc#m1#e!%?+U-P_rH{bsjRtyC)d`wJ1544gcXtgD@FNu`F6zKX_! z+N}H@+JB}jC3(K7Vk`?qFMZ>j{+HkXm2(!GJd+>w&V5^LKF#&|jv9PUSyGZpzaGvZ z5D~5U6r+Wdxf-!2THeV~nhLjQJWJ2Az>Us54JQVNQurj8|K2Mu>b5BzPy|E8x8A8ulE9hh=#DkEjoNmq|iTGBMv41+3 zoje@XFH3e9(j8a2<8$kdn)DKZ z)P(mc_aN>ZI85o+B=+g*)~s&LA9QPCl=ux_qHhe)F23<9oA(=E#LPg+SHOauXl{JE zxmkb(2c%=PV4@PdPI9)G&_I_=LsJ^)UQZYQrh7|R-Ck4L7B@3Kxp?M1)eVT*fa)7+q! zeKQtb|w1NFi|O2@^|DaE;w$aU-^qz@uX{@diCSpjG1tdqi5< z52qGcZj6fe6%ogmVvoC={(Ly0Gc>!~SB=0e;!?mC!6^LoK=pRh-L1f-v7b++Ja_8X zwlLVDzVHIhonsT{QeXU5UEV)mS^S(#JR)MBS8e$EGjP(5;0IG2R{1$j7pLgmFMr#{ z5^&}aVC{m>H9Cs148I%BlCrd<-kY1Xm78VqJt0HH?n(l0fKZ5Y=-Q6K9uZa45fz+b zZ`{3ss%D#WDz&wRe%tu8F&qZXwg58PZn+9{oUn@k^N2x_L$yMhv0#lyQV9gT$y@K z9aP)=9M#trn&&&^15-L26s9}+!uU>fj$!tQCw(i_F!W;ikA2&mhFTYVXM;iG$$NlX z4sNyvv9;s_fN0Z(0dN+ex7lER7<;pxwBKvMR~KoNH%It9bsNeoml^;)owXYMK(gd! zZcP?{3^mk&KN=6P`c@0e8>&Js?2o&5mM(4^nZDB^>_;| zE25&mC7xMi-q4C=Ff8hhE@t-oX|#K!hU=6)y#`er252ud>?`Q1z`H&@K0Uwu_xjs| ztCPd}$=SQ}%hQ9}$@y8CqaCPCy4JHseS`n#c1Fa32hBPV+2P}keeUPDcfH7Nk5Pz#v^ z-(e``=>7YRuDp8o{d&HOqSo4PjABh!QiMo!t@9lSz%c6t+V>A9*Xok*CHIH7IS-OD+XHc7g6$r-@ltS8L{i5HQ3c*bQ_vHXf|J4?)CU z>7m`*+Jv)+tiVHraD=~7;Zg#Axf4iE8@O;SzdppBYCx-)EuK;Zn&YYv|JqX5n5`uFXohrW&I1?gFDY}0uwG_y7)0c2%(Ob3vH zW*qOm-vApN_xeG944w$~hP(&fmE>1+6}$W12k^piuX*n`KRbBM_UMi;FV8RQAI@r* zAFgW0NA=6|^IE~gIvk7LmPPo_ClIgH01?fA7e?-^Z#?gI3r^e3K`;z%M^w1`!9dQw z;60ENwmfpOraa}wu3wFy2P%)hOE8unIm885KkZ+=D9`&yV#7K?p(G^r^%UZf?;$F{ zoDO>Xk&+@Eo?c0w$mkwKuQCaS_mbEk*#vkrBvrI=8iBQNnvIdCdb%=lKzfw1^=&fT z!=B2s@D#a0Gg->CLrCYF+|*Y4u8r`bBPg(2h|7SDP(!)HiQtm+Nw@?W14dKOISi<> z;W4G&{D!x{^)6-?ll=ozRN2XXo1f8s5QJ;!&AM1pWI*26kTWl%S#+W&bIJm;NRk?k zQ@wtX zEkOTv)rb3^V1P?=+jnR&J^Xb1*Z^1dKjpR^!!gh*22V4YVwT%+81yJU;P|4lWo`&f z0eCQdQEikpAPIwHjY)IBZbff|qv!FzGOaA22K%pc%Ydy-^(XsO1|mUm6MPE@U(ei( zagTa3lGG-J?9qpu8IbDU(Z}0F;y6?}mdxTe{Ew?0G#(gohm63wsossnvmwc+W-dng zUc@l93#s2cjr<|dU%FJ~k)AtqWzl1fxR^flX)U0E{9oSkC^>oP6pgSQx?ZgvT@rSY zYKql1l=2EiK|IJzNKo4lPED!FzjxX<_-g>SsiYUk2w#E@b}8JumS1X(jc&qBMsB9x zYsuS{uA+6AZX3y((0Zh0J5X7kkkbG?2`8XbYDvA7F&<2&CjIK3tq_tv)8-5ca_fPL;~&NxbF^GT5_ z_3qS67cJuSxRz^tWSHRUOH+To&`OdWy;8IW5RX}Gs)Ro4`5hv%TV^43XpP!mR}XG)k-7O*#B({RVEv#O`F#;36Zd%RF;0vfQ=<@78}nI{Z^# zr+;m2z7(z>^u@Xs+2X;-(|>F(cb+Sq6#`vqs2Hb*&Y8%i?Nj?Ap}i7A*?vs z%5_8PbJ=_a?ut0g+TE_-VoIY@j+mI(?_-y6|0<8@75fTSH;!-a%@f3up2xMNP-LUg zys0+dRI0aom95I{>%BdH^Y-=DPUW_;v*q91yxy&}wl|wM{+nvEwYyWIW?q!xSmLli$w`bjT=*}iuwlEt{7$P4}9}tfCr2c`z2A|KTFJ1Bdw5XV8pvF<~ z+3%HGK^Lx)LO9xyyjtuK4n+s+M68-9vN686zQf7PV-D?1c&JQ@%9p$ubk3CA zz(~3!W>{w&zK|{bm2N&+Ik(kriINGj9$Yp(vekEjp4d5SdPRhMha+7e;5+SZ8!FOT zX7Xuw*-{>^eVUvoj6+UBAqzio$5A^__Rd*dB~C_(3Pk1trUjZCW~Vn=PIpMhX1U)y ztD0n+o+*oyqDH+>&p!K>n-{5x73b*xnQ{@9p_Ypi7LXt_g+)#(yKmn~y8%j-ahIQT zf(QOHMj0hyFiR2Munys*(|qReAKFS8*Q@Zob{S>lF zP2iav8$FQ3G-dfnsv8+u_~vv|jTa%0d6ylFtB^~6dl<|BE;hC zKP`JbL@v`U%s+hQB=uP8$v)*_9Bm@SaL=SgiA1B?fZ`c+nH-ZHdnYZpj2Pw_crUI_ zj$US;cVS|>2KjF&SmY3#s3`2ATWHXx|Cg#pL|kQG1h;1^(sW zTuMF-V%>wF)1fcER{MAC7M;Xp?*zU#e-nBK*kY0GETKgEe-$_gm9kZ7qHRG_-tEe_HGFVa~XI=7Nhr0&~p|dn2HHEPHkTJomX6}R@0#IHE)2SRiJ&?p- z_}0@8?`tPAhWMfM652@H$9umt25pH^b$}c;x>v8$DJ_y6^2!^IS-*(m#Ji4uJ-2n*o3q-d!!Zg8d!vtVgu@B`>7?7Z^F8K|dB@WG zgUMLu(w}Ge2}K#W{1USHbmZTR@9wPiK2yJT=VzRUd2G#@;|)?-Q5rtYX#RFH=9#f& zPbfRVW*XL{ew)OW)-PG4qWB1|E%Na-xS^?*;6)vxZkJU8lH1DUqTmKD3SzO~-eS*L zs*Bg?WN7?OK1Ns-NkPIh3V9D99=Su3b7R=Yu}bulR||6(2IB#*s3caaY$bD56xVPj ztOyE{ya#B$VDK3cdC7#*b*Qk!JkyyIT^!6qn9zNI9OaXvtBsS3tMCuE?ScP*R0cfz z;NQ>*EqUQ2Bj-=!0cs)I9hhr)&SYbO+3T`Lp=hKtp}rNhvM-L0E?=UQ2|o8OA0IX4 z3TI{RjqwPbAoW$zq?oFeX1S>($5%K~B)YVJ7uLhyy#CN1w}ReN*ErVHB;@R6I;i}( zM|q9P{0q;>P?Dtw;j58^D@)(tVpm8SD!s=QU4UgV>k`mC^H}m(HskCHt9g!A2l_veRyse|b2 zB>FmtecmG-__sjIfD&8K6<@zJ19%@U--~l{RuSQ>GjBEvxex8nZKP(k8)XQ}4gR)~=@_w^L~>_tRO%|0+&A$( z_XAwgr&pe+f=aSO;e+mGq$u=rNb*H)F18jKdtqqG3Nr}vUJI6G9RUJi;dQ9x)R^Wa z^YQpA;pGZMc%XJoNQA5%s+{5N{LyH*!rX~&y@Vc6MZTZ<|MTt@I0)^Zf*1m?tR4Yk zd4LE52aE8(8}u2!Q(PWF5y-zr=V{osDL|Ggs^zJY%NQ`q0>E;#33DYD0e+uo#Hc5X z8DmTrot*5HJEP`-pyrg()*A315jyGJ`5O>3pZyU_HgI3eyJ!*_^P{E8E1a)V$9V;g z!Y{gHAi(Q7MTT2rW)c~AGyq^bBR0kJFBJBzcMjDnI^zHw%AvU?0OY~8WRA)Vg`wx; z9^y3`Z6Wc5ws7s5l#sC7x|C6N=Lh8`^VO1iM^+` z`p9(f2b^PXgqo;UOjXEbPPK=i)bU}m3?y4SbXk$yd44iF#Chtx&ki)RnyJx87gNv% zpE(MhoqJ-l&w>GbiU+EUP39lnapu+mT7MW6wdaR{4B?$zoy(>tW_YN!HEmi2?VOoX z>M0*W5VRDMjyok&-=axil0ywAuYlMrsW^!T?-4m~kH)kcz^UL;mtPVavi_gUeC)05 zd!^S~<=yJ`n=Rzhui<%ow7pZ_sqE}k-+2F}>W|z>Cig2hoOX# z`XH|0ERKJY<8$U^RENlE7F{BxcDvM{ahPx+KlYGCvpmNoy=Y+AOlY_GZ=eg9$Yk{Z@D#p-gf=DE?BnH14#Tzvq zgI>@@BN!c<;{;DnYL~~}L9O<`4*&Ac|G_;2i)8Ge{HcdiiE945)L>)4Hgbp8V=A2% z*H*0@{8g=e=rLdiSH;oQEAQ;5cfTsP|4ZX51PczjUEB{dJ*BLxIhTQ-I%+q|e{u~F zwsrz%#SUl)E3Sh%{<YwKLoRabn4-%q8Ty)rR0NViZ281F6tOV|fiRT=ze=R!)NQsC&JS_#Ob`XFdj+I+e0U{FK?vxl838;K`kb>7$)wq*W9-GF+f(W? z-aa3~-a^O1Rz53WJ(xP+$zKVu-h$^h8BZ@xo>^3|=S0(6Y~i{@FUr57A!@vyks>$l@DKqtE>RSuz*boPaLD<6h8 zuO#{FE#2|0j|yJ-Rk@6QoXEP#NqFk@wqReS7^<^CzUPDgIXb^`9XC*|RS^k4S3j#i zL+jS52e4D%VWFz3dt@osEZp+i@HyOnr>Neoxsk@-pyze2; zPwa`G5r_nS#^;X$ueCWh*wB2W4;K&+yhiA$I+I~%5mN}D^7Y6(!Rdz75A#yeP%!!z zIE=I%X5#44X9e-N_muO|!&-ygR#(2mLY96dBY3FeXEV63Z22l-p{P^;DCrQ(9C}`- z4Ko@(&RB+Bia=}yNaQlEvWSo9SiJ$xi%ye3&vXsqFlqiFK6EcFoyC`P8=!TBI9vqz zMq%mlF)5A{NQgXF^+eovL9Lxhy^|MLBlHt(A>>*-saP?j5 zR0%$e&)8}Px#^A3{4n-2*pb@E0&%k5wFg*Zbys6O=_6ELAo`{R`nZ_m(raVXn!x~Jhv<8g zR-rgBb<6^njP6t*{dC4+GU~imToJzmQvNVhi3qm1gU8S_Lo4L(~EbUJSztNSx`+R&eK8kbRpDnd(CV8+iv&4@-{;)@tq23ra;*!*4O> z4R5tcTLNvho9$q1v&{<_S}8%i4lmLDkgL+R+VxnlN1~B zIa~+^0g(d;PC<)Ym1-e4`2;xRFgx9hlGi1%JB2p$j6NgzVYUi0X(6XdO+sQKUIZ1z zrvHTr#`(`%;{q)~M;97dNS|%E*{Z(0Fw!sUsh6dU-G=%ni<`+;;Q;9=QnE`mfKcku ze7-0Rsb$&m3OkarC9ZGzaO@(=b0N)6KBLKG#upb)WzmHc*=%I;N>vMz=Ui)HUOk0I zmgE_2iy-|B7b^u2D@E{R(FP`;p_{~%{}R#i7JX&sY4kDqrn%fOc|cKaoBs-m)X^rN ziXJt$tA)HPWOKHg^EgOn0@%|q(Debxn^G@EdR1PN4F+gwg_@O_VrEJfjedoAHQ}yQ z0U3HaTfk0aQVo@1*3c{eXQT>xSsF6)FW(i+tt3Ye8}GgN3Gk2f8Boio%g-EzE%jMv z6;oc3mT-ZCU>r|W%*R<^ZiZSSdDPV9(dZ1F-4SS(TcrJ}Kbf4z8Qu}QI+{x}X)p^j zK95i*hans$6P8tVWSlVdByyw6!a{`6g~_Qs>%s(=vydYbmM5>L_X@E#S8Uo_RtOmu z)+Q`^TGA`*Sx+lbQks*lLj#;gB%JYsa7N?;8`Rv;FjlC!E?@B?z^?XKb7h`r%^B~C}(Eek>b3YA(*I4bi-n!fL}vsqRa z5ZeTOFgyM;9++zW!F2mRAd5m}g}LjhWEmAlD1DXi7W`(AhTX> z3ju~0B4Z9X#j@K0G%8}h%{C`ey2As*_$*EFT{py@1T4tRJbose`d|A{K zgX|?WG2vJeCqVl>oJ9_cLQO(ShrraNd4y%d5uM`0_4f?+OZkq`e}xa2S3AXcsEA_+ zF+?03_t2*C3*?pGltT>+)V(<+aT5HAW!Yn=!n3Q8G(iYnJm`S4|Nx zbzz0!c+Lg@)ksf5yQRZIH$<2XI9J*G88zqx^+1g{iU9q``v&xSfW+Av48cd!(IJL_ z{6~P2Np3SszHy_4?DyfvL@frv<-(9KyC)6sFo2>6*d@Ko*`iW4bHk(e?G`Be6)t)M zAM?M&1Vw_OoD;ynP;%+pGYQ4?-`32t?5&~OZ~Q$EtA{m$VF|!@lA|A66dj5XMF|f< ze)LJj%;6(auLLH~fyHt~Y?aKwA=jF2L1G@&-&Po3E*=~jw2T>}K>mh=W)WjSr*&p| zXeb+1Yb8WUc>~-}NDx)UbpTvB-}@7?IZ0+ox&q~vIhJ33>^I@%4<1eW)iUfLzWXWF z5&7->!7R)mx7W8S)JQ)C^h*-{-wE#EqXD$Q;Hf`iqu@S(YCL~1U?r9X&~)D_dEBg0 zrk%^CH^<`4z1-xbLOL2lNeQJ3)0Ym)$aj6n-Vae55nJ@gZ*&Xh791i^mLcy00jg|Kk@6v_WaYyIa zt%>^lJ6iJc9(wGl*gL{#x(Y8Aq$m^7?;E+Wl*HytmRVPdof0bPl#A#B4}=zif=J3T zLXUbl!Sc|Si~5_Cz*}>N<-)K96>P=0&z<$IyPWSe6(3fnu<#qk^EH#7{cH6k5xQId zfGmd6q|r^JGdUlDx(zsA`x>%BCYu`j!8PEm)LmwGRSn4;+ndESQk5sl^20*7ZyFfE z@k1nnCPR&uGX*n$j+lZqc8Xe?F{TI&4}I4X1r{n;DfFnIIz?k`X^duhOsbOrT0q<= zm{o-95Ee1fKKs6=c+9s~+eS0*5j5-G7L!)PRYq{k$`{R_F%~TC93ky8F_+VjG z$s#7M?F6F4#NL--=sYqbgzJv1*9mc{3v(We+~s3iBq2-+uua1@Ta@dP2^I8)yUGYq zFg%6E0f{HyXhSx_P`nuf_LP#A-Y94piZi-6wYTs%iwD7En#dAh)f(Dfc1z$W1906u zKEPYJlp)o9li?iMk@p%4MZFGFhC_oGE84Bc;t>M26cywCkxEF{#Iyg-$;z z^i-F%&_QD|HQpjK1PELt(g7SkK=eO&dy-3K1nE_;Qj+=$;-f#S0y`PPT_k%?0~CB7Dtc7# z{aIhDJXY7lNoN9~me&uh2C^&{(`SRSdvJs~&Ls;cn0@Wdd8y8T=T|x3A2QH_)}~31 zBbY_R1#(VD^z7VPlSWQV0CsDh;!?e?cyWnz6V{Z@BjzV3zOLKMSK9Z$b(YLURBJ1Y zFfcgJC-$2jEJ;ZE3_N0JvrUSr=DIhSq`I$_#;pL@o_aM*eHfA;K!HR>U~o9TDXBQN z>L}4esqDRXO_6C~@ZrsJb6DG&z95*n9>ql@9BAV0TeY-SdZUwXMf*bI!4#N^a zq)?$z`kb^()APuSt=MHz;v|arQ#GiCR(1ui5yG_uh2`rb75-LJE^1BCR^tusQdg8k z5|A}ssT<{q;wyvYek{qn$l_Mu<_|8*=`CFuSm1hads|#Li^OTD(Q-cyyP9MPdFr{O z+!ZOFvXaQj8A+_c3_LtpKo z88JVS)=Mdv$HbPAE0?*4GS;dC;$i?a{lfC&jLQsFi_8+T!zsud1Ds6aR%^}cgy2rS zO%|J`im)s+W?qlH5y2N~CPdEyb0ZngOI;%Ty zn$h@a1%TbPOeYKli;tHNk}WBeI&6a{J;<5dWnWA%aMj@y$linU-S6mGED;|Wg?XgX zq}UorI#l2CUaZ~yj;un)b=K530gIi8=kzT$%rZJ%qHZiVTDj1*@qa|+n2cEvpN+0d z3Xi4*cJm5hN~L$VwNuclPLFovHs`^JWUAnNrsLPNC`=YEboKK=HTTJG?(7z{wU{nm zp8JG%s`I!jGVU*4p7Vr5`*Xp zxuO!v&1JMP{B;o0)|)LO3zlL0UF6*q83R5&IXzZEV3Q1@Do9j5wF;ORC0`^dJdCh& zn1l&-s*p%jD@D_R^Wov4j1ai$zR7kVcRevnHoEM|S)!IWbbl^C-jBMSzeyt%xD5am zg|Z%b>hF?(LZ_S#?v}k@nUK;&Nf3?$xkr@Dd{k1AR7empU}-alr8#K{oDI`k;QmAihNPU&v?Mg1Rw`6u(N^+acN~0>Ku|4xR zhXVa{XR%6ioy22Ug4H8ItZlS@AFGyNHpR=V&K{3ZHuF&oQ|g;@V}hc9KU;-!vP^WD zg@~Syaz?+?8t&^G;&~=Fk6BsZ-X<19Q;2M2-!zW5U+|#b1Gu{b58z-QxpNOHqs#gG zM8NQHGzU#994Yo8hZ*jBAv6JvGsipmZj8z_Dab~)un|S*2iJ3LB5Ug8pWU~SFWJH$ z`3wnaOmK3CL3#pOaG{nKLd@)8;(k8nlAVSHGNGu^GlfBUYuA$Q0!S3eTf#8P#C7Ba zy51V(aU}BU?4}Y~dSc0^?dBk0b(D7)3=muuxuR)&8R>{kaEMsHu&|AAhH~ZR0{d`* zfT~F;S#sUHiUp^2SPIbb{EUmH)+Aj=u~a)3q9=(798hsw%k(Mn-vm>&Zn)i`K2#{;+)smZc!`-6npRldH~ zV+ZhKF);vFnR~_(w=t9Stc*c1+(0Y6xX7-WeTzJA|4BH_#trK4HdI@=5)cXSo#y?< zW~I8lQK@c71v6Gy(kYB3wHYN2h>y$Ez>}`4N^|#3WvjXE?`>{Y`9rJO*xB3NYBX9~ zyRFu3J{-cNBq{8H0u?!XU*gW71vtd%)y2WdS*?8h+i^at*A-?3-4wfIJi=%rX{(?U)PfNp$elukIZ$Yg`~i2tQ1}V)AY#<_r01@)kNi`zJ^c+`rd!eC3~4C zUC@nt2hvf_h8LtF0X9H9!Oq|2C0l!tkL7S@63|J@5L4tj)euDa3c-`m>Y_gM{oWi0 zIjM$#E92j!u>v(?T^Yb~hfW*KdXY@7i^3pk;ZA}>5UGcV6vC@@FHBE>Eo`69gl4_I zS=p?Vs?}0ur&fKvzqzx&{kmMKRQ|f8e}-M6+2A{^w^N8~pJvlev{xf%erTG9CsuTd zyhFJEmMjO6`QuHIKq?{81bH??-qjk4nB68W^2fe%YXp9@e8X=Sz$u9{iTK`XP4GDE?`(Ekw zR(ZF&{bs8IP#rvvkG6NpJC&Wi>KpIBa$s%A6Uj}Qt$zRxUa* z&&s&N-+*Y+Lvt(u4M}W-xwHsFpaI6%O+dh*cTg1*95;qIg<)e zpgj*X1C^HyUmo$#pnj@3-JniQO$UCz`==ppZii{S7#_$;hCRD>B61(7dGJBhs|r32 zP2%w=03b4C7HGgwOH#MJL9_(0POawh*9y@ZL@A15>gyNsdd1P5M%Wf%#;!56pg)R9 z?G`d?7a(?9Rrz)sPr&{f20XdXJ@~xQV;kGgrHJUjG5z)ALJx{d5@KXM0DuVFEy>hP z&9w;Vpngnl^xk%5yR!Ty5Bxja`XX8IrHtTB;lQO|mMm5#1Jesh-uPVPqh3TR3;t#7 z-}pJuI~7L);>}>eSwj3&P(?2lz&-8UH3S~ESC!al_+090we;UOfCrqKPh;cl*zciQ z>i|w969~y@w72KU7_bjHJa^waF@S}8Ck+LFb|5MNN{^b4o^GWSk{rJ=6@$s4Z z@!<6B@um9l^7zO&rmW%p>pd_7m*d1Hgk5i#u)(zGMh<4E(1#fn7sdLULxE;*Pf~#^ z$QY$f9A$o~+L}|0u^!+vQ49+v9n){?BBnh8>!o^@^kp?+}Xk3I+ws9+<>2ElZ)*qmfATwjI5_z8vKPWV zaaGO}JM)BA3QGWCu|X;#$NC|hOwhKJTal;A3!vUBPGZ-5yRiGAv>w&&OX3r;Z_2Ug zG!S#{WslSVe6BnApY;glZ)zy-1^4*sudigUkAJ&3I6K0x$aa_G4-W>ywkh}sVlInzCffCp&P0Dy}Qx9dL5WLy;5Qv zhXl)a9sPQKd8FtSzx~4B5>pLn$eMp>42#B1@gzCvnd)7yRoAXla`e~#wsyGxX)tPh zV$sQH)c=GK@Tcw*kgovj>#r>f7;Fwgagt>8Awg7Gxb4*l_X~sw^-)o=3PbR68Qy_A zF7#+<+Nwf|GIF{+1b2=y%3RiWaC0;8zYv8?^-r`}JRC0}B!B+P`_r7(gTp9bIX`38 z2-MTthCBfYbHSX!ST@3CPv`3VUG3L{%i~Wr0{h9Z{j=JqLnavXMj9mN(@7WoBcxHQ zcl?MB7mTJMNGs3-pB~!12f$^KsB_w!WY%6Thi%i{+!Qy38jdXzt{_H$UWMH%9{Z<4 z_UqG;e>1*Ajz~@$=T2W64Y};xnWIk17=n!sDU`S(`7CINM4FyIs1qXE@Reys&?GBB zyyet`4?b=jA6;rZUIS0TW*5UDpr+w!Go5&09O}lxlJdhKEA-67GMCf>O{8y`wVf%; zh5j4(inu0M#Z?_jZs3;w0@el=jc(GSC}?*GFwEOu;P6eXY;#FJVp0&L+HF~c(OQjJ z`B<>k$?40n^%Phq)XBrA8-(W0W#yt6z+HV+JNeDqELYMDer@d2qumR-XeeD$Mu0N$ zO;1|&o6W!0zrqLJ?v-e3sSkYo-YL8r?OXa@XZsB3_IiH zSQ92!Zpl9B_e{ISS%_l&NZxLYU5poMd}}Nlfiy%*i6$~<*BmqFq=z6pY-A>F(@RKW zlKy%zU&WkMF2Y`G11vyX1?u$KAj0J2H&7@_5>T;T5ARe)58kO_F^-c_CF$KE&swEg zU#qWPt5|_MGu5$%6QX8?*K>Zrj*-?hCl_CKt>Y3ZSSLWyiI`D;yA}y{{r79{#mRB) zop<@}(A#{ywJFLt0Ct@RkSmDxBa9gt+sVW!Y#}OE#b{G(nkEcqWn*-Qm!}nB7DW~S z(>tQVGj?~mPF~fpd^ZGqG>L>D4B&Obk17NW&Z4pfzTf#jtE(PH)YS{Mz@28AQ=?Jk1oKosUA}>5n>SvxE<&np>LH#tUIPW1>*r@&cdaId;t+=YvxrKFVMPoZI*@21+8ME zS&D&eR2LmT&}r0zV*yGK*d;kS)0yE!(QHl{v+A_0gi2(*gHc|$4?pmRN{Rm0|M;_( zGV1q#!ND%i3JvS|TFz?yL(c{Y%-j@tLy910E`2Zc>|JDe?0L^0!Djr7Z1r9nF*!Jb z6n6@Y#%km-cof*6CJ{MZqRqD29p_O$CI~hPTX?0jkP@@I&I6iRZDqpdGYw%f#RG6m} zD|5b})jSn?fhQbIF_G`3R#z6#%xk3xUh83Ebwp^?EJ3vq9hHoOJdoXTpTI?x31ivM z61PlQiCA*0UaZMh!_4myo2Nb<4l1%l4UC(K=m1(BKvpX?3do@9PY(M|=(f(g)WhP= zUAqkeI42wEOd?fHYf_Hke&D=QM1s8%4fP`Xp7C!cH5_LwOke z@eO=O05L`K!K3=y3kre#jSclD^_OxmxO<6XA3QN|19MP%VLT$hAo?~$7?Dt+2w|L2 zLxnf-c8SvSygQ8>zr*fl(3_|yiXeSJa=EOw_WlUsc#N_z2(7hdP#%9ysXB31zdXkq zqAS{59cwZ%iYs}$p@Ssr7BTByecCN3^}v>0@24u$YQFZySf(j&%3(VUsm>ti{VrHBtEW8&Az`riD`O4*m$cjm#BHZcugofOM<@qDazIXx! zu}7xj3pWkn|)%AK#im%;)}zxmy}wZ z1bMEzp?0eco!LD&R+^_rC^+wDXuaM6zK^;O)B#>GJU8$Tm#hjC;JL}TF$#A{gv`f&kK4n0m?j0Xjw5#*AIUd4`OJEyz&mu>@&|qA58RTBZ7hn#0+D&$NQIY3OQw%lEJf&ZT}%ZVu5kh z=(T?rMYG^FxU1Ep=D5Uos5b?cSarRr|2vbA5`+27h* zwr1Tf^v1`&&7)IhUa6|qpJ$cTy;9|ktg^blT|t33GU~6hFKoz2oP#+izzH=(LL$fd z750#Ed6_rLO$b-L&{}tQcD7#YDIxdBe~h6I2Fo6LRqTgPh<8Y*Lg{aJ>J=Q_xA1H;p?O0x9=)@Zz_97)y>1hgFLtm(S#dpX`*3L1F`x=N9Slr@(vPz{iK^T?sa=noT^FVOb)? zg4n|l!3W?l+>dW)G;iDm9XySH2<>)*f2(DHxeW)+ji$U{gI7xaQ@#uS<^9&y>(cwJ zon(BG#>&oaDIabR$L2ra^7~_~dMISttT)rpH_xgqs*gwc4jb0!SidbY81lICcIkhF z)gE7IE=IfA#;?I@kFzs9Hw}4_;4#WmV0DBa=ZktJzel3-Jz`MZYVc?EwmR$9d|+N{R-^#*z%Xs zWHej*@oa9mbD6zdtP-covgnJZyw=)Pf}L$;p;bxRL>~h{WpvxdDV2B9zSVIZ5GA^){UNhfpmYs&n+n=mJ~dlQ7D<5iLJP4v`RLbYpmvlDBSFe z#AXZPPO)uKVPI{HB=#uB-C>$}nXtWO$g!{)PNw~77nNNY+njpa<_3jy(+Zj>{Y6@@ z-$VT`QHYgA{{^2VXyW#EZ>!<^JEb?fjcRGTv0E+ORQ%mirP*q3RkvD|>P;r(YC|bv z|2_|;)MYG_QIT~&Km|8wxLkUJN~uZ-xE|GVWv9HkRRZ!srJBiqVfLcHs<0ScNMsXt zMn=Zz!*|&Ps0A!fDuXJ|8-@~WQbi-$B$dD3!TZ59X3d85*;zxt{-G`}uMfuagRCNf zzw0wot001qNU&xVy2Q^8Y5hC5V?Z|2Qwv8PJz2mqmcTIbB!=x<<^3A5GO#J1kNoDn zau?_qTclDo0#Yc9sWgj*)-;mj&KOxw;Lu*nYTP! ztAVy;fEWHyf*vF`)%}i1Bn>!RB!O3Iv#|;w!Vh52W2a0ZrXp3AKnSino`E|O(0&r> zRKrR1MUz?jhH^g3^|~00UaLY6LJuse!R)u9zblX$=NxV z69s_lfAiK(QT7cSijnuzAQ<<(-8FB1)B?5Zg^2^%@=ykR1AC2#NMe(Js#L7Mbf&mf zJ6d4;TlSRiH37b?q%8#*K<+M zmlqUM;&<*OWQZI~DB?c_0Re{Izn>fVGb9m2ByM>Kh2f2@h5F?`{~Kre&;N#w*a`-v zo*p2_?rsDIdF$aoA<6%XG6cGKms^-^%EALeo(7WKXWMwiKZS{oV1*BwUfN#2Re$1kY6J;}hhg@Z&?<8!bj`KdXnUvDVGH?lX9rs{El*kuz0MZK zax&#)37@YYOh=iFM$gqmoC*|^H3EwaWiLXSs9(OLQLN&xz=Ox-X?p%(5CELR0?@gU zVsP#@x_dp*>q#pTadug7*+Ww=kn*?}BG~B?oa9%u?&-ew0oQ)qL$y`&GyK2iJnShQ zUtXSH)<2xpE=jSy`3Nz9-<~TDIF-Xbo%>}^fO1)m$(Pr&z-$4Sk@LP7R z785N?@50%Ol~c0}U^0bHxp3=OD4W;CvMv!A?ZG`*WL1#8>BI88k0c=YX|#7#ecfz| zk4h+DCo|PczGpNFaPdB>8>u_1-2YKnJg+O2q>cc}M@W9mr~+r8mmeM;adl8@78=86 z*nUO131Z8eCCCMcu{Y6-^k*{}+dr4 zE5JnOL{cv<`#OY&G2?bFyPmbcJegeO? zMcuX;cFKZ`J}dfC&nDC^vDPVRggMbT%9fZtcorfMk_{>b;{6dzRvTK>=_;#xnZsS? z;v#f82>P*los@%Y1%Mwg3Gfl4;#j=_nt7*5bZpwY;5JmB0SSNaH(2P+KoEcuz<6x9 zNQr4a#(0H)$DqTqD|xCL45679aq@y{EK0x%q`p_F5L8wWKtg3YGas+fUjuf1_uA|F zUE)FFVSGmTCs8@Bmsy6|u)3hC&s;r{;*P~I#@-3p*NaG!9aDCu#Sk->AlAYy*Y82agFjR;$Vn?5v2ABcImrElRvd}zL zh*MV=fc*Uq$n?VyN)2>j3yjVi*$IGmi$A^xqzL}@JJNYeg0l^SOrK2_!7$f$0plDh zK6VeWa`-ZSH>_mx&IwbnI~-v-+#vUbHn09h4yEwL$fm)-nMu%DPu~o{+o{$hXz*n@ zGut*O$HTIb27?tn`CPKDNk|hCK}9#h*v6oM<3c8Fyjp7^nMMMWcd$PMRJ+h|8|4W= znB#rR|MJjj3cI&6TcMmH$Lu2P+r%eCtHAJycM!kYepc&6b3m!l0hbBC#k>KSm8SmA zf>;-@@NxeUU8ZT7&AePw{1?A!n8ptmzX3+3DJVxYaSaZ40Tb6w)tR%-dVL(Htvx^y z+Ig(SIu~Y6e-Y=h5e)Y2x%ie7Z$<76%9;?xihG!oE|^IQ2Jbrvoc<@&>fpA^>&SiS z+kZmYQ0RX#qb$RH?T(ZeV7!wif7<9g@P-;R@tj#}IM@CFC}MHUz7)PXnMN+u8{qX* zQ?~C`33a)Wa#>Hetg-~nu}v0ilc#-P+RIQJi`HyGJn80)(uZ1#CB}Tn#H__`*b*1@ z4><%oamfTOWcHF`tlwPFuBW6iPo}3VoPP4zsNCsdZb*1Ig?X@qbEMq+u#mr~BP+}y zIr*$OWWFbbtW2a3EXRCZE;fMy=ghT=)QKkVz8-a{13bHjlvrC#iv94#|Jq*o)Z+lV2pr^wWiOFj%>a(ohD|>Z76oVirRx^A^_o{n8Q3%t}P=I z)UwE1sF>0SNL>=buQpw6sbivzSjd9TBb3KsU}m?OZveE~6r!`#yLcXeJ)Xj(Ky)#3 zI)yI=&EBnJEMNUYSe3kQKXL|#u}VOj1>^i()Z@gz1bh^^5$38Q>GCbkidS5u{%#rGJmEAyj>KmBgMn7!|EQQjH3`fajM=8uMNc((i`rG z^s7fkCCYHz3E@(*u)6SV@Hvg{3t5Ef3;^+Is!7SX!-3(}r*=T+l;KsKrNUt0tLtiq zX0B?AAI+qtM9f{&0|gA56+trpa8#m$H+>%o!iMg$oXiLy_I1Ab84m{Qq89~@pgywS zLJ7+l`;AZPQ$1lMyaFE)q*b>8aCW~>fN~~lbHeNf19W*5pCMkl%ogbGYBP^-vW9no zXe`q|N;ae0^x#zKsruDf&PPwK{5x{Ep(7)T%zUI`f(K^O9Lw=-i7#6$|&@#vJ%a8pgyw$;@NyAz6s>gRcB||;G-CpIW=a8cwKe6vN zKRve4k>BVR%n3L|p6o#02VFNzt3)smZQvy4rqTmOOK^eXUw;1WuWwG@{QvB|%WorD zmnW8unZ|S%U&|h~m_4rDzlv0&aR&`ZnSqhRtiIoy5lVU1W zHD%1s@WzYTc|RL_F-yt49zsfHq zGU7hYJ@>pH?XMS|6piaH7l9lL`Cs$ zfAoJBGSdC?@iCPF~+{Y6c_4EszOJ7%8t+`Y`u7h=Jg zIae3aRmfmT6LJbI+Rz2R$EAj&B1A{i%tih-c^}%2WqQdK1Sc0N3X z@vmAJ7B8Da*H;wV_4IqIq&vZW(zBte58jMbG*-1AJ3brHLJQ)C6VpLYjCsMkXGegl=$l?UU{^(0)6=NJ`_Pqo!|o0^Oj@Ai0FM)G zZTbb#WKkrEy2oSTS1ea&fp8B+C1Au=rP)knZ^rhk9YL)OW_)bc^YwVRhxufRwJ~!4FZq->%B7|fwIgk6ai%srOb zfoN%2G;k+*1LeJG67Nh0=P>`U`@_X0E(Ti8gSxT&mo#Yu@9M(>E1J2DXpk)+yV>IH zB4A+k`*Av9eI@|TaxW1q7l#{OiI$gU=jt-+b?$)j#MWunw?3&^@<3^7n+opZt$d3T;uT#C{<_V)j?_P#keLyf6?P-VPw%mQFYHB=O>gTpZ9pDR z;IChJ-{V)W9+4H_hqYYsV<{(22n1Y7<)zb*)I^gkw}DTgtMt@o_U@zm!$` zF=dNTWrs7DXEzfFpy$VZ!&#azvEoITD@XwMj$M>&+Hv{Sgv#g4zqUyz`Vf4Dw$1{2}jwN|3BymPknnVgWJL57Ays%x%Y@1Utz0NbDL?l{ zD6;GbN9=MGTO}VPY0>Ib*m@wPjv4&p21XYs;}j@dh2z5MPiS#3o(P$RF@y|mG?nh4 zY?v~az2JH7^e04@(ch5MH*=pm-NE@8EXC+#6*?{ie>w?EPH)u{a9Mc0^>$Q zD_9~1U&pn-4MQUPa!WocAt~yHf-mHSFzt&G*r`i-kf&nC zO4-UD)kB4mY(nJHP;HNx=EbDY$~fw>?yEyTsjO$09%EUtUM((+V~>nxni0(8qL3&C zN&4{O@Lr)!YCpxoO)!VO;!bV@BBH(VXsUrxE{`B{4CXuviwj~iayplWT|1OcSDMwC zO`m(r;%{#i(hVnYq))6`Mzw;Me1led^gy$Pqxkudjls`hwis_9KI%Fe^Ia#$2LVVF zNDBOHD0;OKl;SX%IQrA8x)aZo`jFFPdd_>6xSc7oeIyCh3)n*sa|zF~I45jHOruMW z;97q?dcyYh2?CNB=;BWU7x(xSz0JUmgtQYznY;IK;bkkBxga%N0p?Zu8z$K976A-Vfl=v*!JW za&7FDkX~^(fZMF`6)(8adZAKi)r-YKsZlLi9dLmi!(U5HZAB-$))txF?$P*~DYJyZ z!M562(WHg}$6Q5_&ohQgAJaGSiD}{}#x9UW_)kxxF``l7VwFnvw1lzdND%f}HW(Rv z5(8!m45R2SBvS^4^`g97TV_uVCn~toos5Z4$#B#~J45MLc#X~%XTi0&b2Wb2$dhB( zc<6w}HI>zBs-b7^LH+!(5k3(i?Tfp8#N$RcLPgd)=(Vw~&2I8^6_bvwmy4z9da<-F zT^F&#ya`jwD=_k$5FZyP31`hZ#csV>taPhUt6VPehh8_Vwd$2H>{aT$Uf&$=0{CG= zRy4}-$>z>F-q1?qG))J1DhAq&E4=j zspU@z)kJDD zi?yRtW20Q#s5S~{4*uN&_KnkMROljZX;wdyxHj}Gy>YHim^j-_#zcv>mfpo4;?H0v zTObTy){M6iNrpx$lx&j6{s*Y%LBvS;thp**~GTYc( z_!M;QD>?(a?wOdg3Cr*zd3D4dNo@lYyW=|G(PKYoJ#k@QjfQBX#cVh>PC(j*{E`9f z+Rs4_;Xb*IAm6AI>ZNM4QbchNJdcm6wL+~}Yn7V8FAI{SEaaEQZPwnRMpz#AQUX!E zy;JHAH9Zh8ME;r@GgWEAcjyW@MB^4|`VO569mE*>37go|cY5P+H4YY!_|olQOs>Fg zVqgU0iJIWiY6235#+bs+#ac?B{JJK#NY&-QCT0To7@i4&imEM^tU@d?r!9G}lm-~- z2kBB2Myi@qw4Mb&>IFD=iy>LLvIB1bO3L)Qi(PkkAYg@G)lFYJkl~dQ!(}pp4}?2% zof+M}VrYD=m2kY|O=BJdgf+{NU3zVP)cYaqzS44)&Xg-M73$*Oq0_AV%*znh)dC5cBuHlQ+1tDnUS<|P zlZ<{fjXKeSxJ;pqMYQf9qe(OR{lp;(hawY7kuKxNvd9~^;1ge8{M^hP8t%N_hUJ&i zNVxtIiJZuWX~WoJjs6c1KL+>lUb}}py15bT+QMd}SZdmd#aGkE7#GO|l0K-3aj8&- zsc!*=mtCnop(xMkeqBi(EeF`Yqi}V8pMzWkd2>hOkp5@H)I(7T4#p_ajD&84V}U6` zDmE)%gY!4ELL!Kj279#=GW}yiJC=X*#qQCz{`mVh+uQs4V|(xA_8a~2&GweH+Bl_0 zUV1nQwZ7Hk(Avds^Ia@KrxQf5v*H#wLu<@^K8H`Mr${Hc6)yl&U()fQ?l?zY8OfqXtukMVX;n}G(Lh$+cr{n4P zoJIH^zM*l1zG$=t+~bfIxvg*P_`%yZuMjmmlWb(_!Z*c$as zERXe<;pBI<8npeI4mwbjjwM*en8XSRX-ZbBX~z^`;z! zi9@hwT?mK)DE4y-!>gIWey39f&k5JV?_LOexBvQ}y}yND5ymV>9v?{boyX6u*7N-!e;$@y6*}=qiX#CF!UuX}%Yn5KZhRHKW7fdc z)#W?*FW+6&uYufwxty!UoxO16#_Wy7(zSW=hNa0xWXNMHn|Lci`dizFP^5&`Z2C zJw?F6BY@>E*$D4Tf!4k!?#Ucdz!;n)gZ_(eVuI)m^q@Fqdt^%+Zc{+!N#kNNrfk~& zdVPEAjVZEebMIM6elqDJdJg&L5erm-zcHY%I~Yw(8(ds($bp%yEg+>?H`QbIvmZAt zhp~nG@I78y=D!0w?FVcGq?KLc$<&Q)0fmMKA7BB^?54bckuA$KX6i|cFpk_2L$7ga zPBy00;Ubl>H;8zfH*AglT6Qap8#dd+qusv_%7x-gP17dYU&O5>_K+wO+? zn~TIXzrqqc80Jav^@9k%pXX_q(ckGG)}IEKAFAFL__gl+dJ%U0-%uX>qrOI+(EOy; zr1ckD2v&cC&SZX|DIPW8X*bnRKwo>K>j~((vf4c0uHSsD6)0M7;wy9XcY&fEtX>3n2THBY`j5jJ%4!%6Ubcl&53 zc(bz^lpB?@NXV$f={(QuTI*ffAMOf;meew>)5$ToB!m~k51|UHOtGX1 zLLCzhqTCy=WSk%wmxi;UX+Q>4@PqYHkm^2pnL1HoR8U_@vqW_Wx}i{3F8T;n92zYM z7LzIwVTiJ2n1Zo?z{KRLJjCGOHXRg-@n8f_gsQ1B2-Fi(3=#$Es7aXvQZ!T^EDz(s z98v^qLMPJ&{A=-dB(aoKr#}uQk9<{h=K%DW@++7Sk%Yg1FvyZ*+6V`)W zwB=yh0Vo;p8V+5JI5oWqZV;$LPpVL0K~oeia;1*6&kb-oII-ITKw(S(aH&lJbgrH% zEi*%C@{nY}_erf8{Oal?nZAb_7?hD~tl2F|$2MR{UDp8Gzx*$LXE=!d{wFxh#mJl` zE5DWVS$jKl)^xizMPqOUL~0TG#ARu_2yV%$#U43|Nd=x8MpsbY-XorQI6#{dNR&!> zMpo3c{1x;EB+j6PNwNdk!w}lA22ld1#)Z#UNIemJJq%bMIw9W)t)#Z+E$JwM7Z;I1 zH76Fzb~r3&)cT%wf!eMGVM*eg#MGjcI%+Oe~7>}|V(1N-$HR?gt9Y|Lw*WKefdb%TwIUs$v z)t4k+n7d%m6}wc2R|`39xOxaD>0anF!Ml)HO(rE17(%Ou!q6Gg1pUUCPv@Raigadp z;9m+4RKW_Q+f_sJM@PL~1`qMpI^k_N3QqnK{D90r5^(W>w^n(@eHZdsG3ncH{#p3~7PCGEx zpd=#P>mT*I=OpAC>+AZJep48YPd~>|k8i{n0`-rT=|92}j{_BPgLM@lz+j%MQ2l)v zU0l*Uk$>Rrelcn`>9P&r zJ?Pm&1mRFdw`ZRv#ljx_D^39cLH_{L$;M1!SJ&%qh9ihF(t;qcD7h*qa61m~#V%lU z0F`QPKp_(Rw4|#_0ICYgv*-pXV`1+XpkKT{F z5SB!1K)C|oV|qr(Q;>*9y#nTYSa!Hn5g6*rN;bY&i>GU`y66t+`U#l2mVI4=-BFpmwykiH*75Zqr3ftd6|sIQ0&GSFMdMpE>%qU{4@ z9NL}>;W^m(P`r(jEps3L$09t;)w|PXcfe~muh3o8NIPurLk`#n=uFgs?G)|-4WFHFk!DIpjf)@=dosp%qG+n}iU1w4b_k45zb8;arf;7|zq64qRC%5lyl^6rm zmMRBdKw1sjcpupVX!mePpVl~7Br`>j(1AlTR919xVo+#;&GXIA!CIkPnfcsK-yS~v z;``fRv24I~I+&b6byy)O*zzYbXS=n?*>3*s?cs~y_3!K%?+&~8_3iJ(G8bzKFM`c| z_sk0MfT80oJHBE>u+vy-@apq4ChXCL2QN_Y^&q-_98y5Z35SE9L=ar@zWk{`R$o8j zvI7y8w{2w7Oktw@gu92+jx!PnZx?_<3jH4k2?k5B^VP8g-mWe}){;4yPfhZuF+(a% zN<=n$^di7*hrD-?LHJE7P^0m1ut0vKkU%Ih$Kr~)$0^T^OJ{m9^3=3u2Sr|=Ly6}G zrfL=pp=vZi))GuK49Fk2;%<(XYgTcwkuTMcij|F0ZKKj!B%|1Et`h-1_mS-u-ks)8 z-)Co~R=(Jjos~AKMWjqGyfd}O97C`>4$n_1U!7gt;{+EG1lx9e&ERlMX#xny^I!g^aITgV~D6%LIAE*>%lV#wvylLIyUVrlAvf zjsM(7u7+U-3`21J%UapiV120Q>A`}n$(U_^kCXPy@Cg^ewi&`5CN3ib7rF6xrw`g+ zy;iF<%#si{6Mfu3pSN>Yxve+q9*aRTQ*-U!wU5&{@yMbmJa#FGVl=XN-#A2eLxTX( z0T;@gWVu*vnvFj66rlvd0(Go;D)%_QMQ-Zb;Q)qu_#-)$O^Fdv-4rNK66RQSkSGWt zU}!8m>>_GMOkzN9wImCkqd1fa;KtXkX(^0gpsz6f+C*4ZUzGluxEs*UTqjO;$Te{^ z8MxMJJ1<|hHXB>pFL#QqX0f$ZDsOJK7o{GoWg4;(=gMiLOF0~i?b>I1ZV@qwKwVT8 zsHJL$oHX1(Ds#%@`w(1v#Jk^*f>$9v-b6&1kr{tB?NAwA zKOLRpY5c>2Rvr9XDxiebWZYfv$^h%UI`V&o)6t*2s#F^JSCv}UuSVsdR?ja^v0?Q4 z5vH+UM?;2?WK?9k40FSrSfN$>3#R~5c*{?pAb|INQbUcfhJj0>hW zlumAxeCWLh5Uq$fjv?oQ?=|@fLgUOzp!;WH=MRgunr*RgC)(SQ3M(|&3K%)QbpqQ- ze?x%e^0J_8_jaI*Js2S`&%-Oq^VY_`61;SitQ@LutgsCX{#q*Wn6#DlH;0fPNK0M)5&0&s&3pSA#HpXZW<821sMKrv`(YTG$4q|TyWwN5ii217 znAg4!a%PTP@WZ{mTNaH`8fUfX|8jxcBodisly19(-_T7;tTPL1tA0V(4ZH6P7XuUy zWGvLW-O9Squk{CCx|QaBfe(nI6=1jPTsp}8Yo?|iy$5^YIk}Ghax@wt-wHo3&NH}? z?748@`@$S2$NZ*G!gpn=S+Fhy-`>U|b&W5?qF@x*0vnPQoB<$%f%?j1{iuzq7v=Tf z^9*a%Zv;$v(Hu4qnSf|B8o%UCOOBO6HwR#q096d1DwGw9NCXw(_635>Z z-pnO>DU?gXFY2C&E%MV`G&|cOIAz~`*mbjS;l`CvVsbr;Sn~NCpe*;sEiEDG)|>#Q z3wS+Jl7g`X$8YHXHeqF@0h)ggwXQbIs#5tKVbF+WnsYerK7QIu|62s%{JU>gYw>>$ zEMdt&8Guhh3M4vL6<&YV1u)Wo{c%(Q1*qmx1{BJ^w?8ljp}({xtG!F3BJ;_Fzxvc3=Iy)8ax9!2j$2iQ zcWDP3v^s>x0$J*?qPbvueu54;CO=EoA;I{FOo0^+@3KSU0Jbwz{Ea?*#7M#I1yG{ugfW;9YaYJr ztgN}Dg&!iS+hpKi{m4Xy^Lmk$YTAQAvt?^oYrX>Ns?bQVi(EnmHUt;Z1#91o`m^0&`%kXOMr%D`MjgJFW?36U)PHVL0w+hfV! z@5u>f(?7J1UxfZ8m$oV@Xd;(lswd2ayjJE1dz3q?6{gm$J=~uEokTpfiIverpW5i0 zj(y${>!weylotAnOOir`af%iuE92ak1kSi}E3>se25BszRJdmmVre0!KGZ#wu=BH{ z;EH$zN|uNyA&idmP#8kVLa9|rxh$4@@e}xMsQ12|dY@fPsJedYuu9=+8xaOq@WAVR|XPnZ}o;R9Vd8$_!b>@sY!P zDPPN%OL?@os+Oy*Qn}G=|4Jco`aX81wFEG`Y5zeKm)wDM}PS25B~Yz{4)q) zqV#Q>A%eC%`#rj6Ei2njywepLg!_d7m zmdqLqH4|*Wf^;Ekp{I65V_nXCjzFO@y^Q~^Pm9LlT&2qJZrIt(noG7nx$_2#( z3E)X>xDG_wzb8c=t(%bHbu`c#e)L9=$FIUuKFuqD0s#(2KDg|N`o28kHgrCkCJ#Sn z%4TL4rn_VX{@K%zXfPKw`=(vMb)*Hc#`#it_8731Fz7ft#9fmcGYbzU7hX?1DCJm0 zLOP1&P|}oD3G$`nsgBSo7{EgU%qVrR-E&w`Qm36bB)6lehL){anF&zgv22OHmu{Dm?Q_iDe-}f$>RecZt%_b4wd)~|K#>A zc0Ydi&2HtpAG=rIUVK&FJ1iFWe){h0)zSOvx8Hnw_3cmp*FcBSwY?v^#r+@K*D=UA{15R}mD#XrRvb1*cQ857-=p3k zk^!PIVq{Do-qd@PW3c|*;kSoJ+j}0gWmLbrJ)ip6tRL5_>8Gwn?<4l0OI}SGKrDx5 zRkX(?XO~9?DA|6>1bI`%!k(onJE^(k4OJ7kp8cbs{r2dK*Kc-@zMb{tt-DJu@YoVO zqfN~k4yk(rD-n-M&E$#v;!wb+Ca7?c<{>igEQFFTk_S0!6?RjzzDpn2bSR}bQY%fK zLe4^5F$8_25YhB%0m(?R*y<$rYTlSg=)Q6FIQ{dr52XE6tERj zL(#y8LsyV4{j#JcV>~A$?_<s_VOHQ~?vuvX_ zlblyL=+8bnBth-XlY1y+4OFY~M!~8d1<|i=CqLdqw?H#D7m~RQxGY;8PX+8T`N;7T z2&X&?+y|*U4xW@C)8G^nl?ZYs%nCRwq8vRLA`lz!=KhMu1o&QD&cobVt6Bx_TFlk1 z-#$T`%>XD(YfpL>FXZ58tzml_yn6?NdhqUD3!+;ms+RNpsNT(2TlHGL8P+@ba=9Er zY%A5e{j!G$LIham;n-zRVc;x(iJ`?e>>q$1*_LEpv3tRO$A4oY#oy9Q1l6A)e?ldQ zq&vCYPywOM_KSD#%Eho=>r-H?LV~OJOU0;GX@<>uF|3wqom#EmuhzS*N_tQ67{}h( z9ctD5TOLM%*6BG>AkNhlVe{8mcMMx{|J)|>Tud>i;2|Ku1>j#^Nn9uy0;=8Q)?!MTdM@}(Bk zpA>DL$wkl=QG=6Qi8_T|+`fmsb75%Zy(e)tI$1I96$AnlpYfOO-#Yyk*KM=7T`jk(jjaky7sYm~ zT`d($o13+*%FE3f>=;{{wf0t{BDt2$P2^fuTSyDsdAZ$aZ*FZ@wLR*>ZPqxsn{rOSGG54BPrEhHk*~&cD3HzY1b>;waQj| zyI9_-l-uRfcCoU#U9VM3<(>L=t=_7Zx7zJO>Wng1K8eEfF1F8Hn9~bjfem}Oms2L> z&`MC1b;FN6WGn(1@jnl?@|fpB<{<>>@2%FWG|=+4+Ewl1^7>;pwL=+kuGrHXT|p|x zEZJKwFRD?5ge^-7`9Km{{KWoo;?1A@m#OvJC-`rU7D9|Ze;j%0qE{m%dQqoeY<7#S zo*+-Z6E(taFRJzo^4v0!41*Lrq?>Z27SXKN@025=S-;ebN}X=ER*X9JF43$fXckqX zuA*6oXchs@`eD5S!keTX9Nhj%l6v=PmMZb9`P+`c_Y%pYw`}b14FnTciNH&-QGS%0 zs515_goQT@$&ODTPf0BT^28y;sP2 zSOV$jRXSbrxn8#x_8J*6Y>A{NNlJ3}rH$_B^w`Xi<*YF~L4{b0oMyt$eBC`0ON{fcv3)qXJo~BtFHg=8{ixOm8@*b+(k#}C z5j28Yw_XjqrCzbzZ?vkdPO}l!`n7%;M$lrTS}C`{(t9xA7VEuwwRRg7wlg}i-5Z3b z=tqsLkG%M#PEi7n2ATW^W7o59r2qA?^=_}+ z4I7P48QMd)1_Ulw!%n4Nu9Z6FP7xfn(Q4G9PPw19IL%tmtPLlHd{l_&zCVZXJfCNB z;AQT+S8a6qy?U`2Rl+8YHY&G@VD`mIu^u&12D;ISN~KPt)~VDxVXIlHV6XK~v(+f| z8-0kEx6pnIgS+>wRfBQlpLXw12wVLytTf8~W}{x}^h>Q)Sgcga!0dXh(dd=?08hPA z?A3dnu+pq|>QSdssnyG2)UQWr!e#gC|9kh|Rk3pv$A8)Wyv*~il{?*Lr`9UB%AH!V z)aZ1Itx~_$=!cb7t=TMf;7J8$qi<&&PM3bG)U9@!Rb25fsskBrz)xohkB@lsr3ly#b z145nlk=laD4vPi4bI}a&tL(Z{Zx%aI)GPKY-LP2+qein?EJv*dJaW|z4m|2cH1pJ} zt*`+&^h))pjw;H{E^b5Aix%BAEoAnLKPfFQ^=hqBSSoix!6GQWQK#4Kg~0n#zl%tL zZm(7<)yq(bno*_J>Gry%dZXUyR!ZesH|liy583dqPrw_^Y8U9+D2C-SFt=Ch^rNWT z@Ac}~V5Q%$b?UWx)PnNX={11hm1+&9Fnn3BP^nvdv%eD6?iOp%G;1*Ml;9bzHKFB} zn#EqX+G>J4BkH4D4Ey~asCJ_Z@uc1WC`#2%59({V3V~+v4S!-%-Dx#@z**?s-5%_i zFvXUt^>U}vgzOP^oApwy3C2|JwHi@a4MWhhN~v3{xBB4Joldp)kd3Oa`76p_kfk7L zfZM|5UoB$WjYgve?pun&O0iq+!*bCFb!zo%)iOQ=L+%!_U+lORLY;V!z-cy{z+X$K zJ|Q#0?dw#_FqSkRU)6iq8u)SrxZUeUtyZU4hK)KZhkXP^KoIRTqh=RBVCRh{gtTyh zg5&LBFzYWo&Qm=G7tsdm9Zn0G9wL0BWqZHP|a;x71ayQ|n=(eC# z^~>F27pPw80yFyED$u(c)>;n|J-p5T+M-9X0fy6wV0x^#A~-0@kgV{B>Quc~tl-Qc zSN3XAw-nV7wpXh4ffm(fv5G5QuRKV*@OS+%(POUg{X^1zUV49BHB-9yr2O_*Ir;@ejAfADdBis}c5H|zfsTJmT6&{y(lDE(_9YN}l@kqd z&v{YN34^VeLR`FHHf}3tL%J9d?Fn=;pb0Or8YcS6Fx)yhu?eD1PMQr0=3XBXW$VC} z1Pc*7ITb&#UJN*tri_x~g-1wc%sX?VBs66;bN#GnQ8Pe@2N|oWn`N7!z*y4?wh(~c zMVthy!1^U6?u3U-uE~eNHQX z&RVVF{mJ|GBAo-cXd#1dY;L}FM+ad!h@EK!-2HnAEI*}*^55~FiVDkRhM))M( zy*(x-6)q;AMxRHCp%FUb&jP!K#<#hcBmY~2*eRr7!jSirOn~~~Xd#jQ6hTdNgE^c^ z0F>zq2(Uy(3Ce+!N|4e@!$EHt01z418i|hVo{}F?i0lsp&dm(;X>C+0HeOEF$FfZt zeT0ZtM&)~FVS+rr?H~U5)%N!GPE;BdTb)1SpRL+g{*&lD7@^5PHm2IfdU+4av>2-Ro(uDa(kVoLc8@$4)S*9DkgU7ZmiZ&L9yVek z!{|Qa|L!s456&;rbIeMtdiB^jVs~j_Rz}bacXSSo0VYT%@QIS3-PtI~&iNt#vtP6sZJ-E^|I3K4-BWhvN#L;e>Jr zW`&ZXZZZf>Nf^g2NIV(2O$6`zBgOs4AOFSAe*+rJ zzw?i`{4j89*5iH7@y{0;SjSJKh1#s@wK(FPC2?&b8SMjQ3spOqPz2cszzPW<@31$5 zHK+s8I$@07R;Ek2oDZ^|2S~4D+^|WHw*7!uvw%bCTL?;)o+n$X6D`1_TsuK{RV}ICMd~m*LaQ+NhbWC{dn7!L37kHyVw{Ut;zL2iWrn=C7oK+r8LjSEJ;G_j7$l;Wn!(s}5( z7hQ#UzdFL?GU_sqgS8s)D%Y?mo*A1!3N}guxr+=P(iGb(YDV>b{apZX!(`#m^kB ze8A*9WK+<<{5lU`q>P=yRY?n~#F?fJtl@zzUV-IcvD~RF)~jg;{AIO{iwL#ox+<}t zk=Gs1)%9rnK0q_K_n?R!RHy)5=P~!kXq66I7@gxz8w;wi?_KFT@)fO9nv9?GLQAF;Ga(6;ct8?3AW$n(J!W%D*zDj*=> z^$=Z~BXkS{7IIdiTo!`fW5TAdLgXYD0w0k6!4skNKv4aRb<8M(a2`7!ibYw7%B;QU z16v$0a5#ZTff19cBZ^!`-~de`!2J6uK(aL@gIy^& zDJT%L0v3ogFt+BQ6YpqA0#1Ztc8HtS%d2rtAZLKuNT`QRz$ZG?D@AqJuN!Nzx#TuBK)KLFNo%(On14 zbq1$sXiu6m$&n9`shAO^`sWU=w*eq33ybU4(5}?+ZkQ8132sziWt~k!1f_nHP~4Ft zgG9v-umSU60T$(3_(7_P0%ZP>6I0kWQ=j6{*h z7Wzb^CD30Opzsi+V<6HL7W;E_;zT`?aEyusV0M6_c`9Jn$0;5s!{7xZKB!cpjDof? z;S%6L;NZ$mRW!k2<3Exi>j2xP)Di4%WiNTPZW^AtORbK9B)l{At)Pn7BT34LN*fIs z5^)70g)WBg%v80hbgDLrxrNFS`)Jx1b`4sEhEwAprH4}HO5&{cI7E{xkpce7DaCsI zfso!uKpCT*Q>4Ng1zy5+XQ=cx4OGw8LxEjjH$)ONo4uN<=tvD5%6jD z$OS?x)vREuq}s}<;J~ajj3?#30)HSPbVYNQ6~fR5N!JQ10v99d7%PI{i4p0PE)o%B zV`6%cR|L2Q=7tb~I1H`~bxExNImrW*!qHQZSJzOo6Cc9G=+9v~1ISNww2-h3W=*=^5QrkwBIY7=oi+t;bJw~PwCeLtb zyx|L0RD2Fz2d!m7=wh?@1d0>-+@tvP@al6O&N#d_>=^I>R?q;#-1hxWP$G`+cD(WsS9T z9s<>h`29XlvlOKm(&Z2q-<1tL1RP1nA>| z*?`+ zumW)g3lg@ymqJUjssO-LO%pIO3 zkxx^Q!OajU(!E_sR{7Q5ZB9&7HNxu+4H=*HwGF2c98VY(5*N)Xm>_~gC_@EP!h`M! zh8sb1FnfYV)@UY)`8l*;h{3pVM`sblWym?md1JXA@7l4k54404YDdO*(eOe70B&Ol z>{s%3$Qz4x9}q^MEQ~?Ep%CK612`1$#f<}V&qyv5XbVn)*2+^zTWm3a5HWy@at^p& z7WD;E3Bs(*ZWYMvOB9Bs3dDs10`g`LX%^mB>C4D(BpWLDO{SNZsO_&}IiS{!F0Y6a zI<$&*=To@9M1e5^qD2Zk7Y4-ap*6CpK++Z-EqoGUh@p%+;)$b3o~%t5fkQ-nZU&HL z&;*oCtja3D{Aij%@n%tyVfF=B(JDhz4bTqc!$(+Uht8j<%Df7KK+_N!w|Ik90V0Nj zK~VC8?Z8Q-ygroENqBIyC_M&=jL#}Bi;W@sm|h)t}hT8=jZNfGAEdg7e^HEIYn}%(pU@F!3$|L+5<{sQF23I6GVM682^9RIvy@!lP8^pF%S@8;na6cL8lIZRfI4t|ZO|!>naqbt zBh;aZ_oS0W8@~ud1rFZLIU&mYEIqckz{ij!)oN#!bQ=#A|F$LZn&3997Zn_44*XkeHk5*55&SDpZdrXFI_a zF5oK2KL%n2nv3CUG33s^CVp?H06K21x7q?b&D+c^HMd?bEA++a8oc5KOt*)hOK&l* z-#>_$Xc}~-!#6-RMR%+(C3!obKq*@1)V|M(~0j0g317!j^~8Rfq3TCE0hCJL)f)MVp5L_F(?)d3`ETcHz!7E z(u)EnI;8oCsuZ*SNJ$Lx_IRW?kHB)BkSm*)#stpu<@K&5eh}2HwA0M6d~aqk8xKz7fXK zxB*yedy0Y=5go^qe|9$LK?FB3gb2<)*2w4$(Qxwa<@k+!JkI@^Q{1B?#Q&Z9kN>xS zii#~BJ7lZ}N5^m8ca_PJaS0$pKPYVY^>Su1Fp{ZCQx18|^;WWg+W&SF5PA2k4BTo^8I1MzFX;&kNFpjFo(0R#*t;4|%uHpcuz@)B|tx@@Cr~|u~m~@H)RD>|) z*%T}>PtUn{p5Pz22-%$03mZ3UK_t1eZJ5nWG^#;72#^X@w}iC>fzx8p!8A0Wo2Nzm zbMZl6ppo(@_+~UdrvX0|Fq;VH-bM_j*r1Lfw9svd=WRUXjIVBsjf8%nH(t!$^xOMJ zbG4~s7m*#-2GAG~98r8ue`lj5%;H3ZgTRO2Q+hq*V!>c!t?g?0ijDDF#Tzm;6lNZY z;KG%e??CqpiH@)pBaAmaoZK{-h{~>dk+a;v)MYKv+F%135pl@{7r{zk)bAI_DMlkH zyHm^rdyjf?#3ptb_Ht?j3McP_Z!QK0;}3`11++0B7M+Jv^kcFQ^3#HQM&E)Tkft>Z zLxoINgFa3`VBQRw+D13T1>SX3RSgQXfj~EeksC{^$^DW zHdeBuZPyq@4Qlt_4_aZEEBFqE1K7?g<#*Se=;GZsd%K%FN3-5LcSu9tO7>>R&qFu% z(DkEv%$>{k>{AIwY?p}OG&6={FsPPmyUxr6p|v`QQwuK}meOYA7=FEtjTlE*ij|Oj ziAzoS2!C~URlQac30sVZ4FL>MXg49XQ`Xlr|0KG)c-L~1@ zhSEm0_)%byZHhUAa*`5D-Hn*K#e{K=%5Nb8)yNFn2Yce|#TT4Bxdn&@^5Ny>x}nS( zX{S&5QiJn5XpA$vpIXPNq!gg-$!L0d#%z=+xw{&~5fa2uiZ8?d`|t(00KDjOzL!eV z{Rgch;FXOb(zOSNl3XBC)uPlsbMxZ#A02WLB5xbZ#^u3PoTTZ9mn(P<5XB*}pBuC# zw=rjn29VgJo~LlXYa6sDr#G-IVLgY=%!nfH!H@;Z$Ck3eBaCZBWW})9p?2g@iL>LT zU57W4hl2knMv3`YvKU+>qPoLPP`!eP#y?^H65$Bs-hlyzoA*#vfnp}W4Rw#m?FNh) zMCv}Y{S?*AZSKBX5bBa3OJ|0ojK&(yD`2!F(`0C^0JLAjK}#2wPgXLNz0MS={J2|o zX;Qp!PZ^&h*c-Prs_iM`ljP(U>6Lz-hh)$4GG`Exe8yaYTSW|rEH;G0Xt8&3hw z-+Hj?SyNQ@GLVCBFquJO=$@BED8eAr`4JpDBGaf~l6}HRqi#=#Y4OFjN687N(Wua+ zUN}S7SO!Pkqyw2_XRg>Dqw=EgJi&itIrswSi2QfDQCGl_ z1@ldWS}3hf;9;{UDk>qXO}edlsCg645t}L(RM_#bq7}B1^}v+2TKH+31LP)fJ6^auA`Y-!GjPzm1i})8Q+~EIFRwPBnRL# zv?+sx3xD&p1RRN`@KAi^HjKCktEXsQTA!tDaLlf`@vtSEAG2_4p*FXzqcu~`N~1Pyt|)l7LPABe zE!31-=v4lz&CD^Ib!Bf}CLU{%TW8iZlTdv%g%+2^JI0Uw1XbJ+pk*q_N4T3DKH&IP zpRo-MHJ{Z+p+pT)bgO>+Lbk2dKrc{t^WlN0Z|=BAo6efIpR70Xc>J#fh{q zQ$LklQ9~k1);yJ5k(&x`tWnkEtH2k?xzafA>qSY)dc&8Mb9MSsuUR({ESb>-# z6|+n_lCi5v#6C%&?B5gqkH|t}&4G{jjv(VQ(zl)}^=O4r=x(=Gg%g+ptVT$Ds?_sT zsmEgu%d<%AChe@Ep=zv#C2V3Gh~1Ljy??6I!y`#B;x(mmPnCL}D)l^7>Y*S&!y~He zdQ<~WALm3ez9X9x_*AJ!ohE9O_AI2~Q>C8RNS~4Im*HtM5tvVvdRU&FF6XC8J+5{S z3_cRG{#2>QugrOKTdmKhNQG_r%F9fm3qhko+|agGlswiYJ?`aC)k!S zLIm%7fg?|qdQd=NRuyh9&xbDRr%FAU$dHFY=m?1TRH>(%Eb;nOsYgpTX#t|ANSV*JXEm6sG47A)FUng8IFu6&?I^UE2bUO zlBOuTLddAgnIPB3?+CtK$4s(ZeMT#&GZY^keBv6INZ*plc5R{V0HNzFe9thN?{{|h zelX9nz!s`HXu9_VDcJDI|vXt~5C~)Y(U~G*lc~rpv zZ#PUs8x0jY=vU1fn+ge7PWZ#iDUhGpdkBIMj%{Yv(CC^H26iCUay_D{1%1=*_3?`t`b z#~j}x=k`JH87<*S16D^!*Yw`lOGldO*)4ZaVQ(bWkC^3Q(j+79Xlv{MS#!KGW))81t zN4oDYR{&RztQ!eqXQ;LWYRbGG)-}M7)`*TaCEfSR;aNfcl!-78I$j<6xO0Qr-*>Km z5fk;!0G05AQaz9-e^!}FM0-?{q{yU;2NuV>s6yWX@j(ay^%meHZt|c-b<2qtw;BsLZ zje8T0SsC5H#LlwdVr^b*x*T^mD-6wB?VcVJij`gs`mC=UkNKcGm4zfKr?N`gBaZz* zM?eylpi&Grtvt7!^#KP^#qJ)2U_N@bO|4g6biMJ3G}z>k>)PFX3!c0IZoy&FZywBU zr3EOYseV#3@O3`4=VJv2UJ_CyS6e`VpK`5!CyW>274x^FlP-NjD-*Hhy3e?*s6^w4 z`a(20gY1Qs=|uBSgHt|oAKEYVaWv7VHFN0VV`4kZee5|065+aHVp97Mf&_G6HuQW5^4emfcan-*(s#xK3A?fqt{NC99QUST zCkq+%!2b4j9w7DDMHWt1Obf)c2@nR)f4{pWo&2b?P{6l9b!p#grDC!4AO$4e z1xklq-U;x>V5{zf6u{a9X6^x1;k#DMy%%41Tfl+Z7w2buEwY2x31s3lFt83_+dweV zEIe8S*H=f4ldBi_FMsu@`hO4kc@f|XL6PC1&q8}0`#i*9{^D438D8BjNG-DPB-}a8 z3b1CnBH}~+i@+AT^H%5%Jqc(v$yyb$dJ{Z9Oc5pa^k7wKC8h3w9!{EIu0b;itK7}M z(es(W0dg!!`17tNvW=8bJ@+B^)U2k!8UtXItPX%dQXQOTh~SH0j$NhHGl=KXWK^O2 z_g%R*9CZE14G?F>L%JP3C1s-y-4A0 z6-w#0jAB(VJ3+z!YedPLe*v`f!((1MZmk(W=|1kP>SdCw$gTs(84TU zO%b@?E)8N8f-g|+OPa1?%fo#1@hpUh$CTi6lw#%-rn8VhMQx94a|h>|cs}3(5melO z=>TOBKfu?+7I3IFfvSw`9Emb(aO|OsYc%YRZ!Ym7ew0GMcvL%ouv=4zkNN*BBM;}1 z6!}HvZ(P9&l(xgp+PrisFM@GLJhK@BP z1iAGl>oZHdiaDFT+nGc)N)xEPk0WH`knRp!cFf>o{3UNWy}FzFVd zC{<*nKI)Zi4Qfj#aQ)(}G`>pHOUWx^l-b$(85)?c$D)cwRvG44U7nBKqmx6slkhpmg6HpagaJII^JvDsE!}KEnK`5Ms4zLtGTcfcSk*D8*tiXpEN>RJk zab7-_mN2@9OHi&cE4MxtQpIw0Ca{DyxmieVSu2CF6+H5DP+9(ruJ9fl;u|jwwJdI{ zXPB`guAhY)c!KB-Eelh)3de=hpV;J(5SLlVbD1IR)o}3Ks7rokwP;PIl#sDK@c1=tQ z^JQs8vmSoYF5NP1##Fns|{|- zM<8tci<6TxOk)kOsx&J}wtWGnKf{;4v?cHD?rm#ak|97w3sLG6N9(wKKp;Zvktme5 ztm?j*velpTZ=GzcuU}tZ7Y3+dSs0B^*AY_&Di^P)l`o-7p z^g($lrm=L6+XJ}M_LMa@Ef4%e7*9r`vM}nRZexr^Vz#tvjkWAzy;@A6$|EJ=8S0;t zV9D6TifX}TX%}hiipbV}%7AEu3(KG73@9GNjgN?=PKeBa%rfCL!<=E!TH5)Fi17fM zmIZ6pR`r-AiA-{=rjQMDT5(P|B{(SW*8W0s4sXjwkfgi(e8~I>H1mwcY&waaVtm&P z7zDWMxSPk>0zG_r?mgp|cH^GoogeE$QXg^^2+@gy$oS-~<0pjVohbqf#7gHWYpB#B zmC`JBiC!QENCt#i+GvWY37&b9_QN!S^?8VhKqlG*(9C5;H;Qq@u&SaLmrj$2XXK7i zm0g2{Mf2oS_%KhplDSQ;=Qf&}j?rD*FLE~br0pqVr{0mQdbi$GKCOMgW)INTEiN8+ zhgTMxBP@?+ItCwejlF%aQH?oEGtGiKs~0MTR=rp(lp58N6?^Ylp^Uf$5r@ISw)(^ZICsq|f_$Eq8huRP#3!bCpbdmWQow06hDQWCF1iV#A~Y;7 zbYKQyp8<2QzzM>upAf@o%R`oRLecgQ5u_57lAbsRBZBTiDBHH!1Bt)@1!%Q}ifP=V zqRJSWq&B+NwW+Dl(<)y@;n>JEu=t!^U0qs9iVe4;8zBtq9n{ENN9!N7PC<9Y3Et_R zt(S|X>Uy!XF7{UJFmK%4c?CwEhlGy{6tc2qkc-`Vvsmd?qgJ_G;t#!USZmcQVc4tG zd%eCn-uobg_0ECM0Qpxa7dXu492P?!O1%yb+PnKlh3&uIe!vz@*!7BV-tEgw^BC%! zbL9Eo{3~nC!B4MYumO5QTGy!7+X@ZwjU!35ZpK0x^UW z;sV`I-lL>Fr7(98IJiqxL!#|KWa;o_OGakbYg@rKZ)H z^gKS|tieV`mOvlERV8w}iWFmz9=o%ffNuY0i}Zq@YAcw<>IcgSfUNaLp4WfK+=45Z zV$qseNG>`CS*%RKELLOe5d%~OE^1Ykc;|OaRZO9y4p^-2!gc2Yl?!x>nw438Rt8v- z+kD?+{IcYGgSLmB8iS$P$+B&Z{<54ILO`i-rI8BW#ETAu%~3zqG8opZS6l4^im`3h zYmJbCVtm4IL2%U~59m%UsM9eaOQT|sK@q#S?C~#cc|N2K0@zuZc}p@ixH^Xk;|u*w zo|!=%sb=5_`oM52rQkO#T_IYoAhN~i$y1S+Y^y^fwy>)y-}IZB+72>t!?8qH(>U!` zro<(S3*&1Tr7esvyi7Wo#81pA{LcLeNv3Y3mEO;gUdU9E7w7{o*`tUtmPU-oJl+~1 ztCYQ`hDZg*7Bv|;_;L!AM3yr2AzHARgS|MRm-vP&L^EWQSe8+2Fcx8zK50CKna|Pz zXD0pFtRL5t65>ipK%&}~xwbIx#^-3!%@P7n4Bo-jHw&kO(2DIKAV5zvvWfc>aS+C$ z%p(*SXg|7oxyvkEk90@})K`Py^y7>%_W@e+PlgZ>j7i;1r|u`4^FY3zdD>~RDH9?~~16r2y( zi)7$nDNdRQFK0i70?WKi2{14Yf;Q|9cCSDTdWTK3!Rc^-hQKcEFpU$&2o8$wxFYfLOP~6ec1>0frNbe z1>rilM8r!^Vxdx61W1?JxM9}I0j|ut*WUD}bpYnZ0aY~v84s9H<2O5-L8DkLlU+=v zr&`!@BiIIcrPBt5CZ0?57uzm3^PK_AOvsu1oR2#}8!%8M?#-@EXMACSHI5$T&< zq=cNqfq@=vlK>5Tsi*TYYTSkK66r+bQtW-8G5R=CBz7VeGdP@fyD;Tbe2@q67=-yr zbcsAV#uH)gFgUxpgc~h;n-MNnEavfFZCn1ok}p>nHrZQ-x%qnWy-V+1cHFyjr8_YJBpg%oX)_luaMz$qkNqZ)pzsK~Dj?7L zROs_<)Gi!@5~f#AYv+nqzV=p_8e+MD)avOF)*^fj!rCbuYVem3<{5Sdd2b}aPev&0 zj7MQlR2PI~Fn&s?Km41X2=v;u%*4EXS0+V$kv77CQN0L_3ZA>@j?WS4L6z|ZwI6{b z1SAJXZ+z2`98?F|#o8Lg&K_)-j`QglifuHqS@Xo{b(E(~*D!Hx78BFrW=L zw29U`AG`jpy};5u1>_E%r=cnp;Z7wc>H`YI^tj7c!-` z4bQ|~^hrYO!01LSe?%mLZ9^8~$pJ^C;rI`71g(ukDv%4*XgEb49}*i!r{nMvky1f4 z9uw-R2dF??%{&1@rC{8e4xNlZsPpygD@Hi-$GrxLo(`oX8X}qP z0k~t?e)Hz_o8!0pM{nL99&K+Ozj^)o=n+UZnM#$|8NpCXy5Wa9K_XI!h$2Yna+clp zTu{&=F`F|kk(^9A=Xl1}Zn;Hkhs^R+Ch8xwHRJn-hnPC{-!%sk1YZ+LG@OYDps&w3 zba@XF$PHyn#`rN$KoV@phJ@lN&oN=XlAPs>p<=Sdb+_>m;-94>K}zd!ZiAf}gnINn z7pyirUWiPs&8Aaav{;&P$zAm(UR%hWYUT`20c~77J}Kdn>NpW<=8j50E}rtq@DD}zYun+ZS)aq4Vz4Fp6~2qr<%SER!Ph@O{H&#cWXA`ozB zjJGI6Q#vfbdV?q87YqVZ=P?`{17i=9>EsewGb89nY&!gb^&K;as6Nnp@R}5#naL;9 zuAN)%_iXI*YWfl9mcu1eD<@XtG%~f0W}?bMeDVl4!z^9%M|hJl-fr zo=CPb2}}$WCaz3bUl2ZY#j zfpbNLkC)v77WvVNpLYsUX%Np4LY4>KCoyCZF(iFN^F@&KEnegfd`bZ%wX-YaAg=gw zbBbl&a2XH0La#7sHwdA<*SLtR>HUa{z5Ue}fBju^ui5_kzA|eXq?EMN^4!b|eGA2Z zlIWn7T1#9Cz%!(|2ZMJuNBvtW&pES1QpBAJltt*%+WbJqS=<@?9NIxd0nKCqQMUwt z#eW(9zSM-#GAAz}^Fc*L(GP2(gw)5dFSx9oIaA~VIIk(w;jfkR)Xyc+8E;X4>jhIY zP*5>AP%$w0JwAj317rh{8%X96k&iQJxDV72D@BNk4fO_D(G)O+ykvK|iBM#yN{|#G zsv^`;jBXf3hqHsB;uSXyQ6BM7Sj{EMIbES%AI%*Xu&AF>_dh_b!f}Lsq5lcwS)^6s zUp!zJgx6gHwpmCpf`TD+fY1k}J4Rx6TrmUlu(=5&9-31%3NaDJ-z|5mwOX&$Z?!6o zn(cjXr_=&yjBikNg%#2ZPZ&3O!Z_P$@{?d3Vy}R7Plz{pLOfR-Xk~~e72{Y0V|fhq zDMrVS(P?)k=yL+*=T{K0%uNgS5&Rj8|N3+?UWXlRePWWPt%xWdzbEeWBoBQudFUyE zO8tfmlh_EB8$q>Z#dZSOvm+luVrRSoeBS750udJ^1CFo@?EvwhC=Zvh+@|Tp zlQ{9DIejY4$>7=(i+WPoNxVLt%5D%3!9+Uqs;l4QYNKDG6NAepGm!_jms9Zcp1ZR!&)YEujQA}%`Jh}k5FiN)4+ zi~guJq}DIl3RwL@aRew$$Z-giq$eT|Eka`9_`UYHL3uNIQB22L%1YDBO-L=xzjh^w ziKWUFt-Xx$7xJ6j2B)4*kPZiY>DbZ)CH`}CXrGiS4}>g08WBH zvyTX?#ZVJik!cH-_!E{WWcV-xc1)CxNqR+`4ywCQqDCATVj~iJgw=lbRCePj!1-He zOfu)z0mJhN(#;X`&tV&`z_yXsMKF#!u33A0%SC-+BKDr*ESR0d4aa!qOygWad9l7%}*S+61 zOG*JbTcbr_YlmAEfcF`4ZIR1Pmf_9&D2;a(v@a02)zt>4Nr)p@3hs}=WV9-nZ!#Wh zd=u;*z80WoR=BBPowcl0p{7~V%v0V(WLB#60FP5z0D$P-ft7gl_;Q2{9EU1io7h*Q zA+oopKs-``bC5p%k^#ut&p{3{T5coAH!6jCsoJa*k!X$Q@lmx_s1<9iQZx8PjR8K~ zvhbS8{ua5;Oh_8%f%&*1$a0R2p6W@o;DHjLL4gvE$nRjs7*1ikAUOc3L!2O4goF!w z77$=bT)~3dFql0+VzhME09BBRBqXK%^AQ}L+5#L2kj4wEYwEy=!W0A;Qji;r2s{3O zmoYt>s#u!jr#|f?tq4Sv57N=e1ShboaC(JIZf3>fNbT;j_LmNPk?8o+OC}-`VUT2m zO3kafRci+_ypl1bIggOo#l^aKX}9D!z6=quQ$ptw)+H3Wq>t7G^=qscg9t5`c|SyD zV!CW0!(uL>mw@_ry9Z`cps-{?Bj5W5KlLI&PdKJTVB$0Qdd-hnxV5UqYSG=1J8Gs9 zoa5+}8pR3;)f<`NHaeC6O50QTSI(>}d-ImUM9rFJ5~{DJQ76jc9aV95jJktREkXm1 zaQ8TTARVa;>#>N2<}*{2x&XpRvG(}6nTt0JX}yhtjAXmv`paoF98HefsB2|27iRKV z3w&Huw%sz)HmMVSn=5N`>3qXV+m=|&$zhO3O}UOl_$0}X$b5!&?Ul6UK2N+!-mB6Wy$L`f?u%)A(svhC%-0c(-K z8FXnml{gO1AXqy81af%5GYv&}&`PylN|IPDPiWbXC5gE9zo=t!!zG3(uDKVp${pNZ zqpv`sxo7dcq&ya(D&MNgCo#=16Rb&CiV^W!jOep_a3(VC;FO{|P2`qW0}G-o*%-|dCf zr&me~{l$Hn`lGt3w3FsBM95P+H-g6?O%m=|gjm`leW-gVVdrPaZt}h_ZDt$XER0S< zgGC>+Y5jigF10`-mQwRY3)7nmR2S({J-qOgbdX~vw?W}P;i#YnNai1#UkF4NNR;BC z{I{=m&~%#E1v^=FZ3(H;CMEcc#ror6_a0H;-Ud+_By`lJ79 zr~5zsFaP_qXZ(Bc-xi6{Nw(Vp8fGNB&vy_EZ;0NP}6A$#9ybW z=NR$l$gEjsRrYmcx()j96BJNI{_W8pKKp}z{x|;&E(EFGyKM#tcJO4djkKAo$!98g zKpdTX#=%f#djtBI&QuV^4MoaW?>$0sIE1WgpA1^Ykv189grI^De^^G;R(=6n2|OVa z+ZL&JgVP;!ZFeDV`0UI7_Fw%u}|Z$lOq$NBb~ zoiqKreI@@MmgM(W^11oUJ+pK6>S(vJ_tWmx-qGI8>!bITy{+y~`&--7y&vD+?Bl!r zt@gFQM6sjjzg$ zipBug-Ot?f_Q&Mm$N||p9vJ0&cL4l`e{$cJ_Xqps-H+cMZC~yE)c)za!(wso=(~$o z-|W`*e|n40wm9oh9>|X6`;lW4lgy zQ?m6Vf}I|$WWI~ZwObkb6nV)D$4y2qf2DcAj8rN(BPiC1QZ$1(F1W=oEtiK(2 zC4+N*4T!lz^^fsZZ2JVqICD`M3YNO7mNLwuQwz|i+%0q|r&UC7URiqN!_jgw)GLG- zBo(<+yiN&B6&-M63X{|DnJhL4@2fap4KAVg(x<#!fKAk$UeWMF7?8ssm?&uqfD>W( zX2;<4$=%E0nw95FZ8DDHWJt<{YS=d{BllPIU;yS9mwXVKKsgV|zgRsgH8(1ajbf=# zYc%j*={x%d$4CG$H&YrolT^cFil=z``yXO>S{ecO+zq~}70S&@t$O@R|KFa|K(E>_BrIm;FYMKJx>np+Fr27&%btJGLpq z$E9kq9-l|fUb|u z;7|jk(7mt~@bp-x6-eR^obRO(L@Nn%lv1Xkyd-mHJ_txu-4yD)R6 zzt#%b91gn^JdTfB-naVGoUi?Jz1MndY1&(+q#gWjFa>k=@1W;FE;k@```&#eI|JkZ zc|fm~0ZP;?ZfsP0rH!axENyg)QE#K%YK7_NU@*b!0Dt<6jg3-#ia*22^9%tJ}#JVUx*MEB#hJ3`?DSxz}wqE3HnaU+;U9=1^HQyTNqJg39bQ`Mqigc5N4v zydk2f<4f;miiQp<1w#g_@bOI`gOttkS2l@IAPNN@@qMLSDtXd=4kib19#Ma?jHleP z3`Y*D3uDQ=N3%RiUU?6M=Bjk<-XWlg_f)y7B@O<9HRzKs%A6#R-n)7{d*AlI+qvxQ ze~H>eU!Lw<{u%$Y&yV~kSzQg~i^<_qh$jrx;i8Wo=CY-pck7t>&Vwi&?U`7RcZ_O` z=XUpxg7({^FJ8adJ^I$)h@~Kh-=ZAgp8t&kL(Pb#rooucexbeSU;nQg|Ih#YA3l4= zziKa{RV-~Fdwvgl(fOb=M(EADvk=W6?mp%xJ6ysrcAvp_9Tk3as4pZ^AE$G`KjX8i%MmhDXLbAqjhkE(+wY{1sqz7~t=bidmoh#D+B28l&D zQO`j`t-~M;1dVshD7gwTBU+cBC22A1;(XxXK+7G3sl!pB@d36>8z13N`W9qH7D1uY zWIVc%5Cb_`#CN;cLf7Yq7?hfZg%Gu|9LHc6APleZ>1JNU4#lf7k?V{i8lu>{uJK%= zvqWbx)v^VJSgIvnL>!cFCP5Qv7II`h#kn;XU2Mx|P4)+*oe%u>!#L0o&hMpet4tR7@Gz#w_1jN*X& zYnCLtGXt76yO4cuoKKpskrl!E-_{3)UU?D3yi@oH;3wmA{D9#&SeW*W(V{t0kdG3# z#9^{20%Awp;Uwn96qwY-qnYxNSP43wOXHz&r(A67($xwe0XooIj3^DUC zB1RGyb!O&68}pCoWFv_NjJ`#SWhr!uasxP9*DSz1EpcV;;J!fFo>B14Xnf98yW37m zq#itDoHK2@De$XUb!PQeJOae!9UGBnJ%>CBvTh9#HrK#ZH&lCrMu7|w&nwY!U34pe z8v>aW$lK5#aPFfHIQj>KyDC01gaB}a_97WCSK)hn<+V*jn3a9NKyq7Kov|XewoZHr zK?@;#vNODELuJQP95MdW`NnvHMX6t&@JH0u>U@M5xhae04;`PSh4@0 zjZS@qUBNMkN?GWoda!47%}0e(uEb?+{r9nvMDIIe)_A#s=Kv9`D0;gm=+Gp@hy=-; z?S`C>o~P6)yS730a(YPQ)QB~&6?QYM_G`tW=G9svOk!)sPV!gIrIdJ)pr5rP(=fuJ zjkkp(hf18l_Atc3p=SV}ho6*DvM%2XR|`GykVs{inu18e3y9zrxpxfeDpm>@6)17O zn0rJ5;Q?c|<8vR<*DdZmNklVu-z~`WvB<*JUKs(Sg{v_UtN^rMYa1TRAOsjTcGS`K zI#u-ixLbCeCwSqE`yGoilsx(2JbJ#PanQ0BmRKSC@+j0STJlP4MSD(!a?6 zIY)+EjGstZ#F+ILoEP72DC59yvv|(zgf=r=3Y^(!S1=l$;ni^xX%nKu78#HRA_y76 zGH2(6A)#mZu@FjMMKg11#o6pIx7(#J)s37vY!F1&4~-L;?p!60Vd)FxpqaIi&)fz( zdtY!u%oH%2FzC6J_;4P2u6d6+fn#pMtr2|LhZ{nJ%bWe}q}R^fOED^Cx!@eM-6A0G%0IS!VHD^^|f;s^^|gZ7b&M6ET-At zLdtDVnmb#;`_(J(p1A@y79Q85v9>+m;G+%0B&}RsPe_mrOn|jy;-8~ysWngq z)d7;FV-U(AhY%Bktd>1LNzLq5l1^Y0)f6($F7{}nbKnTiVb6i}z^aR>}stm>)N z;8UwXgPCkR3R5ZmgAtHfOT;%=8lGAW3Kw^5JbQB&(KtS3r=RRSFPJdgJBiX$V;VX9 z1xRUOMsu1O$-lP&`0rF}8X_UUh%iwmYlRFJwKh!aBU#SPdIi@l?T}_Nxcqc7(6cGr zAEas`xoo|9C9X9HU71Je^Syu*kZw9i9H^WpeOQKUzvA^2q(5aH<8?!jOt@cRYPdl5 zCR)XHA`~}4Jq`FatylCa?s&=J^_|Sj)_3|PiwSL=qetf1;71f5r16K|n}dT_Thj~I z5F77@=)Q3*LV(S(Bg$G6u!3Fui2px(@6sGcmZgcYt-GzOb2GDOnHJi(p}PlU4FB>}PsFtaL?*+4uTK#+k5R6GbGv(v22W+5}}Mmvp}7TV29n^|bDm9)@G zX8Hl@jsAqp^nK@?>weum0zd>JNU#blW)X;RzmIdzJ?}?jG?2jN8!!DV^z2KtOQdw< zJSZAS9hbP-f6sciuLq44aSeURT8gc2+x;O5AFkx{`5+uNrxILrf_w`VaA?F|$fkC1 zk{mp_seHiCb$|J8o7}Ojc$yQ03ua+^ zT}IH}xV_@zYqx3}+YH|9NO=95uW?`CRetxaMAVm@$8?%~n(qZ6p$j?Im+IOwqVQ;izmz z7U<=z0KD17UHL|hs5o?7D2%2aL=cJUqP7UELi$l_*uy?*d0M2N)L8_n=HLtiY!Es+ zya!?0k2JuKU#T;mN>MS2QMlD*M+aH>U6JU`K!zh1cYVaA+z6poZxnYNN`NN5(t{8t zq89iH1O^Rl!nRoX2h&LmlZCk(Xq4JW3>E@Ex*___iLpTGA78?|0!!v^alekCjo37I zs{4}MI(f0$q-qXX6 z469_SB=YMaxTZzov>E;ybz!`=@X#6>Hci;ZEGSH)gxRi{G=k{x&>A{eerOH-&>GrT z8dH?%p*6Iz>?jiOp*1v%JhGVpBn1__tmM8pZxUhK)S_b32Xo@yv+!~AENs3L?F+Gm z$oh-Ks|d);bg0}~3Qghc80%ZeBxN|r>@d}ra}7gX9?wxl2}FhqYE?t}Iz@OL1SCpK zE@u(Z#&t%$%H|N+$;1Qt^B|LZa^~}p)o(}LIJ*Rqv*-_udW^_?WKM&KacBTRKt)Br zywKz6;KPDu`SVsaDSeKG$t?Dty`3tB>a$x*it;dgjxLGajDT}n(81SR#o1O=s=7q^ z1*{2!&$cQQpIFe*0a6%zx>b!aL#0L4S+Hn%-?O$^ex-M3M9b5hFIJvMu`%&C^G1r~ zZ{{4)fgsw^3Y8@*n)Y5U(c^3oy-}lMjf4e3|0zqg%8I1}s%;_KyV{o`nusC|<`IvJ zbj`G(5T4)j3&aF0Xj{)%f1nEzY13p5C@S5JHZAPxetrQZG)E25k&tN9du?_$@0|>T z?Oy+)hoE=}?zcX=5N?Oay0GZodQ&;W8_#x%&AtThaKQpM<7Ftd`HsdWM$C;nREN1|LH&fibPz8u2(KzAhSStW$}niR z1NjKq$o1|ZGFre3B(?IJ%@N9xqU`HF<*j!z`yu1V^^~3N=2*YXvj{jAua5O{~rPh30MNVpEwNPAT-Yy+d zIXJs65j2!jVB|O}84zy?5|(>)HNce)qS#Q*6;(APd6z=tkQ#ccIQp5qbXK{udXn zg`Zwrge25(TP8~6`2w7pL5ar&ay)q!7&=zm5$=sCuvqLHZXN+5QM3-Xy0LbLMj8@qtK$x7OR+3>y+E^) zK&@Sb>%~7VKxZy0-XRV_M~BoT(U(!Z3!jK}BSPjgY}TjsnM6o^^D z87`s0*i}(F_F{5K0*-~lyN60Xv7c6q1}6n z8GuC83C}^1Q1c=q2|-Hi=PuBL4BbUrIThao(vA(fr7i~ifGPgUl{sNhRA1^ZY%|pu zg4ItdlRlO7WVP}oJ*w(?RGd&eMJ;hKFt=y~ECJ2?%`-$t*am{k8Gv_LR+}E{Qlou} zpmKI*9V}54_ePXHP)~6IOq5)qOb);r?MfZ*rk&t%aHSd6F%!h39TiDHz3eeT#rLSX zZO%XQArF)a;b7$*mFjIKUMZl8l3+kmgnrU{1o<=^6ui9)7DwX(A*E53%_j}vu*BXa zR|Ep#;OGtlupp-hjE)PhKqxnw3P6fS=vNzv7QF*kcm~_hmk%5tmD}ZDlX#YC8ag-0 zdHGqgrz=&PIQC99BUMS_dJG=K4x$ZPK_3CKf&iQv6oCRniBQ3SA_-rz0fzlVR`z5{*a1r`n<39Fie3!e|kF zb~?_0y;7^JCxNYX=We*u$jNsB0-h}a~PtH6zaNdxjWifg}O{z7iNfk$&j;|^)7tvwgvku!dKFW9vtL^A65J=M=AhAkC zL*Ob)4*@0?scLe)(bmUd{xlDUKmmZV^GXo*`#25!_(aS4*rep2&eWr_2Ksr5MMee( z(DhtkzO=o2uhfo^3BW50CO0I&G4N8xyz;RNy zCv8E=VsR^U%C%}FoJ0w(Fd4_;Q1Ix|2eW}rXrsmHgF&fA1>OQ_d~{Ax0L1|bC=oC9 z(tFItNMsYGwYunWd}^Ey-IbZkhWjfqy?nIL}mQW!VZKHFfbIur0D@S9>8I8jg=z=_v3|v z1c;NMwepl*&G9>QH-L+B4!B+x^#xLbxsDepvs(l*`x1q*RDrlqKniTShcpX6QIXB$ zH||mezrpB2y+?*N&G15!L3C&p?K&f5REh%QR8TuFoOa!6vYGgz0?C%}Xi6aih#|*H z8Fj?tz)>Vm)+VQq5K*5S17sOA0cBhO3M`8N^POo1^y8UHhV2WmqE&{b8dh|K=HMZ$ z02L@286~L9s~`w8tp`>nIF1_gQG?DFmTqGUc|j?VP4}X|3oIO&jm;ItIgJ{M zY#mX#m}B`RHB}a`T&g( zDce2(;rUcl^%Tb}g^t0X*EAcpUZfO<@F+Pp8%MEl(0Hpf^d=YsPMQnU0=e$?ldo-( z0YKy;exkI4J;nD`6``u53xP%ebmu&h)99cNtNvh&N?_nikOrVLQ=-@~o`2>Y7qxt# z<<#6o;)XpW+?5lO+o9Cea?a>k#AXNqUbCc4<~hEIZ4or>&>6w!jJT5Anui8$=7~#E z=a)~!6qHX}DP6%jvjzAUJ5VZ(wSXP0h)2Bzl*Xcjpu;Apl~)~^NLQo?9%}&4N)S0x zbGDV-0UG%9K~!>EBTA~>(E4@Vyhvjgp%jxm0JeB8v)}M5aQO&0|gN11n%VJiY96Abw-@; zM1sY5u{;)yXtbTmkVD+~DQCn|L|4}r%oTVLoy>^qG(fHXCDC zXf*;IAHWbuYH40$*^nAI^kz}=&{@6fOOV)2jn>}?30At&f@56aJg$iRV-S(^)a04>?Ex~?ZD9%IjwBaSILHA|tei7xKF%G*N|mutjtsWZBnodV%+#V?Uv3_sSYdH6+y$3>M_Ju82_LP!)fpQ4diS920xcP zH84PNa&uH=Zw3=C1cle%vaGzLOrB^YlAP3MSMaaI#bQOu5yLu5D#&u}h~&=F7K69| zC#VVUkjWU!bV@oN?5Q~&%q#fe>9f5b?O9%1oTFA#N7-*paup4Iz(*+A04(rTpxS~O z4@frZ(yJF6m8GQj5EB-Rtpc0eVdWVQ6{1v7Oh^y=kk|oE@I*3W;+;5o;m$jX^CDUI@w=(j&hqTjef8VQLTSB_&IPJ@T) zP%yxej+4wvttux&`}t9boPqpE>jyk4v_wc!FTffNxoKk%2y#ir-ITrL ze>B-?pDzVZt(=?;h?^;Wg4l;_^5KjkyK~@!SN3B+G$xko0*QtW?6i!E%ivtrQQ(Y- zIS;w;ae5HqY#wsqXJL`)Tkwa&9#cDe$b~n_GzzkK$c4Xm@ zkCqGX3^p?9$4humPx}$G+S5~i#ME^+H9a^<6?!bj&mw^BNA7jT9nq*J=^##9k$Gs~ zh@(m2(ZX%*88>D80G=E`k2DgRz=A4WFSj&VCv^F{ID{d}&1{f!8AmdkR$Vvi; zpKI(C8h!RR;Tl0tPrmED2Qd^H@R%z7e0gm0AHU!qx0oS7=nbd~NqxvwAkZp~deR}T z89!l)lB9ddw>KXM4-(-miIbGWB_fG?&~!+b`y*${;5nF$hX`mf%d}@bb{4FNQLdgL zx?&Z2Uo%{tc<2v#`JGLenCGM{(Kakq2)xsGmIOU=v;W>)gy11BUvIg)r6@}Y$03>8 zg6Ql+Uj9Q~{-l0g(Y+>lp7BCI!F;Jr!i#zP1^ z@*M=Eu!Epfh7XMK+siWy-eQ0#9zm`hs|L&5=zZ*#sE`>E~WBoLJR}c&C zst?VwG&uqB+rop1I`iVeMidwlMNZrB%_5plv!%l)$CTd%FvJBOoU zL2S}rR-|NjaAi~i?w*wbPsJo6Ug7!9)=T=wx1=y13PYQog1`u_T4LdJr;Zq;5oB)C z+Fek@EiQZfb6cJdX+r=vD0U0L}iK)$rU?2q;+eB4ImV}|7tJ$W`yeWXca7>sQ}QO z!Y7z--X223#&VMvEfdc-%iWKQ*;p*6KcAxmk)rouy>?Wq$TA#)ER+N!s^;0XMRY}c zjt<=%A@F=dPjU5a;lO~X-x>%A(6iYabr5L7=;u%{kAZ`e2n7b(4~JhqV{Z(PbV!=a z^LBUiVa%BEV*MF}B$;A1rhLNoi~YkF2QTcHZ)9xTe3mNA1ud3&6F9aLK{=NPTtpSC zxg^epX4(Oy9d7s7t?Zar9(AZ&5P*QdNDeV($Oqg-vIs$kP-!AOpZypGmU-JPZzo&G zwsLy~VrU@zW&H|H#cmtLgjVQW)bL(Uo}{e;S)X{1;`@migihlIR66@l+VMK8X0>AlO2d-oww)`DXsaloAc(fB=MPN74! ze3B}h8l{#vu~oXU1IBx}hBy&o6Vf}_w~8kWo8@k9S<-_gD1en+ob_SX#!>JdS|U&#niW9T>>wBv?JOuY>j7!RcQ&!( z1!K$oJW)AXW`!aN93q}xb;#$+AHg|YH4BhO^jo#WY+Pm0qceiW>&B=%92pI{kr4up zC-w7oCzbFpH~ARL*YShLEVQuCAPRalRa=#A<=)8jSb;e~5 zPZ7}NAIwPksX5GF8SEYCi%=2uKkez40w^3seW%#qu(2$Sv3~ zDZ@&piK!}3K8Qsq1*Da6l%2ZVc`7r|aibjEeDJaZ!-sfwAtwdz(2A4tGXNqrJR#Dx zQ7r`h8JLy~ql_dhLSMaLehS5CSE(^8?aFrSY;VJ`4e=L*4Vjzg$ox(8vWOzymAtlY za8xpjwe!(Q4}qn`A?lyr$KPv^XG*kSTa8PU2;qCP)u5f~D^p z@mbV#resN~)+lNU8wpdza;X|6j9FYTP|3`cFEvmYA564VLXY6RRVR+qWBko)x>QtD z*3KvS8t#kK3SqV+P(lkTTFw+Lh^p;U7?uka4Tdsht7HYL2O~cZ8QoUI4^lPeh^lqw zFWM-dibQQ>tRZ~{RtdZDmPxOrdL=7Bj{1Tc6^I#uc-rYTNV~X4Ic>K@EJ*Gz@p@B1 z1W=_eEnC#!Q-zSm)wrX+pUM=9UBe(^N-B`_AvLXcAr&K`m}|zkgw`_mlvv!yQJSB7B6k^cd-AAzt|7S zX%ES1pIM{UNNG-LwDV&klf&%HMC4i7c;%z|U>ckt=3JOj@HgXq*22+J%x^`?nrn48 zuO*R0zeL71G5ey%BC751KbrES`$}A9@Ad0vJ1Z<7hT?j`OZ__d3LnC}4tjyO0+tTP znq(#oMuFqprMT1Hz{(IPRxG_8NM5qL+?IOcpfr3OHCV+Ygi&-jHyFtsHZ4Ujxta?$ zGe9yAElKC7&Uea^Q7=*GyB}g-CSKZw)29aub@HZVoFksaUoGO-RpNB(WsshNB{KR~N)_!C z?GQ)Wc(yWe{bL!*REsz~leRMGelvCrZho!2h)2xta3K5vzfW{K=o69O!3zCnW120* zNrXm35<{YWhpVLxwN_E!8r`HM7Ap2(kj+GnKId47US$b7boP`Ng}rE7Rt=Ok_Xk;o zTS;PKuX?j#P;wibdc-1vU@Y+x;HbdBZ_(ym!hysC0*4Pck%a<^@5Lgz1aRWU$UY(* z6hjTbX~-|=+h{PYmkuz-mYTDbEnDFrfx{CCkVI)%GU1^~>=B%O{8Vn^5}6ox`}4P+ ztfeWv9Sm|18InDrM3O+|rnoJjH3dYic?OPS3+lMdK4C7YXiun8op9mO>o%+7<}~c( zoAg^`DQ@P{&Z0+c(_XBECUtdDz;GBP2D$4a%fS~o$L{cmx~$zc=juquyw0+w!^<8z zDKM-O=!p29D0EZ>D4QM8-(%Okzhz6hQSL}?W?v>8yY*H*1F25W>nsPB%r_$BFcC(dQzHJ1I&a&;I|)6W6(aX}HM8_R%d%y8g=Y_DPea&7q? z1c@#?Vvrnw)S+RTC_xQWZTCbF97&vm!EG33qh!BmTZ}c5oEj4R6Lg|M!TJ%iy%54@ z?L%};?4U^}IwToHw_Xj{yT&}UD*@@9+-*O2XCHwvAfndfMszi>EA$gYdI#gW0a&-Y ztVy*2eWlmUwUVK9JPU-$KqX()ty+F5!z&pZSG6@-avY`fEz6PvI;qmX;+EFHfT-&U zxD4ZgSnnUu1VY@r7eT@0A-5eb9c)!fm5cs1%|* zazpV`f)jmJ5UQ|9LiI{!xQ8M=TP7IdN5FdDIe4ASJ|>Sdt$RB8_%E zwV)wJ{~#P#0tc}n+z8y2$iBf(q`&JkT4rQ$1~f?*U(BN2`q~H>hvFr5n(>iT*apP} zJ+*2qxQe)L%JI+tK!bK7xiDt2S$F>ATy~;?94R1~%oiWs&wO!-9Q80IV~azUoW@`f zYn-Ss_F_=Vc9&zZA~#nrBD!SRJLlpNPMy9CGdx+8DPZs3yW*{XGCno36VJkxgi;1A%ZD>@uM|Oa+_^ zXSk=SU(wp6G)0PWXRqsI^7j=hmW-!=GuF#UE-hnSn^QF9WM7TU53VYP9!(vbzG_Bl z6APn>`?21ll8D35iTLg=tgdjOw9sGN$El#9n@U@R??Qx*d?0thvQaRMYr*Y6lE#<0=uue$ zGe%a4_{c%7n5*VW#ayWXFGFRcSXx_O%av*y_>GDya<{9+4Ypja<%)%Z>alM9S!9}Z z2cLxH-cqiMU{%k9(<-}t`ORPaD*x;M^3y;6ACDgKzn97V`8qhCFG^l0bu{cHRa z{i!_q%SVWW5kpySJ->#m#4fJfDos5{h}lQ<&1$FJ=)Y$qn*0 z)fXXBp5f{qgsgkQGzWz9haVukpyvWiL7Mn*4*Lnr#Zh_D))h{?-E>tt355UVKfV3! zf5K+@-((QODNR9fq~jpq7Bu2!tAmn!AP+DWOnv|=&`-XgsCo`aG9o#jpO>-BsYhjy^P_445B z7l&G1?H3(p2}&%(8`Z+$3@pXatst?T^jRy!{8G7$zk1E z5?kdsza&2SG5XCAM5fAsAi3da@NpYu!?dY3xOC0NmNeaC?1uaWldkijZx0T>-OeMl z!2{wF{NDJkQZ22=M}jK^GR3?gzBWBF|E9S2_H?*+xOes9aId)k)9&Sqo!^c2-#)AC z{j^uu|7q*eUqKve!P&Mq-@LKzns449tOz8mTzc~+Ub~!$yRfZJ2QS43ur&6vW=<@7 zW#b`u#_rFxXBj;-?U_a|UURn5GuNE4dnSdn@j3E=rB?VJF;EF8xfhq-BLe0;Jkm#w z90A>F58i1HHif^dK&h{Jm?h(PkYs!$>;`ibQ(%bbq@n&9PqtCfwlR;d-1 z%O{0et63>FDjuxl)m|U`Zj z^^-=a)i|lGZPd%9^-{UKUR+ymRI0^Ry;iO^);1c|%u4Y-D(!QG`bKSIz20h`tgUaf zHo|h@q`cN@Rl{0yqY)M=*k-f5R;!g7^)=vUxLz%+7143LSt^#Rt#YlIhQWEO%3*8O zuyWEWRBITa*l5%W&03*wQV)xzW-Bb6Y{a)o@2w+cmO0BIBH?i7`Exh~k;E_JlTEnv zj}q}TgkZ&oA?cTLkn9VU!{Yj8d401038%PTT`w2EcW;EvluYAcMKND2<_k$V$dhI< zMSKEFJh1`dZ-k$iZNP&=B!f|E^*=WOmg{xmSxSUWE`Y(5$(i|y!xxU0d*A*khuRD| zAB~rK$$biLj$;Y(g%vE~qKxAN2WUbG3A|J&ZUj4+MV+_tk@3AW0n}0^9HqEk*a#lu zj=5V_s;$?acyN$u-7aj-^w(OVhr?latih9hz>(<*U;9UUtM$0r7}rcmGv>`;3MTA- z?A>n@d4Gt$6375@fIOjx3S-HyPQvxV=H^MIP~WVFt-@xlxL)7fSSz*C4?^R`02m_u z#pY%)KF1&9;RUC;xye|ia!?6b{EfzXmIhYF^ub>+5((1|Y5C1*?eEF*FkKq~*WBL@@nG!u7JM6ZlUIBdj!|^Xn zOX_Hk!kRoHtHxAk84e)4#0(~OreW87x+uVx=zG5zSG zeIX&3>Dk5^e-7q1oAJ(k#v%fFJ&L;`3cR%SiHR6CAW4BxYf5xid4HYl0wo(F40kxS zg!hstCP6bCe#}U`j~GuX5%Q6re-0qulPu&T!6W$Pmju>nPni?Aw@}{~FHyxe!e&wq ze*5u@U%ntB{+kc~!_WT;)Z>4X5vMQ>ur=KDHfOjw!>~Gf!i?u^rpvJ~Mki`AW~Cqg zegxNTD}o1!$tJ_X2psRA(bjMWAFfJ>igZwqqBUTq7SS5Z&nfNcU zGoX#<7gn`L%UN=<(IVo|YMbPw-DkOKM(4!ib2%t<9zu82+NfBKyQ;RHR|Z`TjFJ1n zC==PWCgMb<-ergtwOj#~@$z8-5^{C3T*@kd%@GqI%iDmg1z;m~6wZ*=;u=y*fiw}?iT6X)1A50cEA-J69zt~I1R3qQnRiW7jrJlRS2=LskT=Nb-ZkfCcODcLT7{m^+~7tI(=dslefCzel7CNk)hwH*|GG;m|KjXB1L) zJP5;xgQ66cNA;gXAiaU+ z$Uf#oA4iB#Kv{g3trihopU!Jhz-d;uApF7+1=-Ue);R?{2=k|T{Dx#NaC#I=MShe1 zd@Yf5qLbJnuu+qnwiqpqUndDoQoKUmal97?I%I(o?Cy!sOZ4vgBZsWq=9VBZwy0O)lZ4j;)*VT&kyT}VculLWWc}H0grMSP($OF-Af%M~*2_H{h+J7tu4n4DVCRViuJSnGnKFq; zHtO@jRu2clU>i*rW$cb%0p>$mDN}V2GI)B13h&{FGPZ`;4Nye(T^M{*KY3SQ30|R+ zsGh!g_WcK4(EoGn3gHzfQh+8)FZav_e5WY&g+u}^PY4AfGZW}N28fv6pl(H!ZZ|R$ z1a`KYaz1*Vk~?$ha+l=vkgKeLz+U%<^?K!`S}164w7c3ocN^O=y?Nv~E^mu!;_+$2 z9&aa3`L*^6df%Zp;U=l%4Jn%`2m}Z*i+n@BW{Fda0i%F#x}h}Pcxw0y=@6K};+xv- zE_v-lK9{?P)&Qg(BLw(BNrfp4st}M;+G#+@CbQ~>A=L}~qI@kgMTE?#enG4xx66Vb z_fr7vAWwC05s*K`xRIP8u#1uBFuKH?9W+kzlL07XDf5C0T)YJ4=qOCTSLBpe6FxzA z{L^r7GpNyJk?S{0Q88eWI*TX6qKtO)2(`qof?xAU{~`Bl zjtt=qKk;shhwmRaFTS0nw5|=80%z9n02a>+H#|y8$O%is4q3lO*2$g0GKE59fQSs$ z?uUFGF50M1_Kk{CwA;BaH5xgyPOu^t&5E`08&}C=nEL`bXl88^ZRpHBV?<|1hu}~q zdRQ#u_5psGgpPY~7UX=!9+lStsfJ|4HOz`%BBks z!I1{xX%OUcp5|l=p{Z%mX`h}Ak=Ux*6eT8a_41zVKrK}$Ex;1cpb2Vy0|RWmu_NE26aA(jKi^fb6Qj!-~ zNU&b46W?On&G15YAgi?*T~8)(`^0UW72AZ7Vb%QO!tsH0-z(jTY~Lyv`>?krO))i%O3A zTC1&2R|7Mv$s?_boHMFm%U!7Sl&BggC=`N3qTX9vpa$b;2#-$CMs>C}L>*Cun;rE3 zXhC6j@V*(Wk}Zz&fqKKL4Tz;+Q3g++Rsu90g5G1E+U=Av0i=KMB)|$wI$`AGc7*cL2{e(M1<~MT zu0QgZMr}#my*Fhls`ZE@rVQU@C`s-DH8of|Hm7zIfwUuSZmEj_KcIxaR$u}CD`c`j zUfQOn0SECy;-BPiyaS;AV1&$hi_1UQtb|ks+fZi)5-PHeEvmpq(~KpcxI9r%)BCdpg47Wazwr#0Qn4DWc&~CaG}aQMoSz_DZdy9{K1}!vqBmcf*~AjOld9gnGTKRL;nd zh$}F<>tguM*q9VXXK2_4&0p-jMeL)fDeM}*OE2M6zy{^DB+jzaCYYXe(*4Icyhtc8 z5YqbyC}V|=OzaVOiQFK@++G@X11zE)o%BV-gi2 zuc!#DFgHR3;?PdnINb`YDy^P^yvoMlz)N=`{8i&a5a`oGwej#GK>oc{Hjl#-AJTd?vkqKk^K# zs|nM1R0Dxe?tGk-dNFFCSslEbsY*DcYrN7X*9#N}!DI2Hsbz{^tps7ekJG@9Pt>1c zdm|NaXQ;9U>Qjkdl;n&+*K>i*7*mVM*u(50PZdE^Z1^X^Ewoe9gA&;vaMU7yC}Ju+ z)!Z&8&j~aTS3YEOH8K#Dqac;{v^!tyl8bC{87hUaAean%Yn&rj3rrmUnqHj85Qd?( zz!Bv9I#8U@1{-B{y2B?toPPb%EHQuwuu{zT_^}1C8}>+=M&$t29zqswIA=5)X-=hb zg-O&Kg>gS^eYw3OZ@4Wl#2sX6Gs;=Z(iu8{y+k;YS@T#=4k5$dS~py(iOk~=QG39s zbC3>NtD;=Xsige3s+9YHm2a2(TqUnr7!qFsWfY2pzC zDhZl{(2w48&*UnI*C0KrT%f#@x;<$N+8VuzB;TSu2q?YSM91Oa@3{2AY@id`s8Tzb zXiL;B@D@npBXRH`Op<^S@lr3n$83y5HsRCkqGsQzaXM5Be5VdgN;jK<50l{6PHuFY zi9d12dVDKlTg?{>MI*KoY$K%o4x6b{-heMN5n+c1Gb<2huy_I+XVV~5Q>G7b07c{U z4AoZOhZKg>W*dn}adh7QIz~zpP;mMrs|+$TbH@dGy`Qw3#4VshK_il`O%n5S zXu%MJapMkI9+MFem()RUkK$|BM+^qE1X^<94~-WR00=3OaDga(LV8gm_z{jX_=Zrb z@eJlHiq3$T5D@d2g0?_HMBC`_lvO%$RM6d^KvT{E*UO^5Kq^6)mDw!@{!gDSz z)g(_9NVbGW3!j7-ax72hb;M&=joMIIfKMZOq_606V}LA!CZLQ9K!IfuV7@cWpm;MY z$*_F^RkWPxZ3!Og@> zUP%|O?_FLE?j|M}&Nx7T+ci-#Ml@d~aVUc8ZOB{d79*tyE?uva6D&4BT6kPY1hfM1 zF~FvK(cc9YhMSPVT{jNnoJI{rwvK3KOtsvWSOpdprU^;4yUD01!;6?Bl>zj=QE{hX z#5=fK9h<1|c3>!gX!sulPe&+h4T2VLA3u3MKvg}ZC?|!E!Jvok-D1PmiO#U$_W+wA z1c)3-o6K{35!)hY+M!*Y&lzzgxixhjEv$)45}w2-VhYNqPln)@b^**5;9qQ08?hF! zgO%WHIJ{^9rLia>=&%WD$eWU6Pz&5NwIDT;k|0j%%t$70U<6QUf49Mdci9XPFAEK;#? z(+-A)9y9_Xrt&PH%)#&kYGnprbVJtr;2HbUrarzGN$vE{G}{dBG1xf)d4Pck+$5AT zwX~*#5Vvj~D1bmGNPsCxd#^L%d`CvYt;F(JG@{XVDnkx&k{w$k~-h5sF(D4Bbfs}JB%E3-Tq**RhLd}?30At& zf@56aJg$QLV-S;u$?&xpxpS{coJOPoM%-F&wF7pVw<*53TdyJ&^u_QJykaGIwsY`A zI@ojlvLE+kL^KUuVa0<0hl=HHH7gVXMVjuR8+{LDH9*aqy$j9Bo4hRoIlZy$wO&iy zXcGJz@buFtbKq+I8J$7g({WPfa()bRLa{_kPQ5})IOIC)S|Txt?X6A>ibVs1sPn%Z zn+m2E1x!>D;i#B7*O4JFN;iNlAR5*5QG`4rh^0?XF8&IWXWqBja>kr83FM9>7g9LL z0Z^=*Gig4~9mPsQi{2eay%-n*jIh|Qul2Wy!4F#+jgBQcMz|Imp>DPW( zz}0+_78CsWGFC$^Jdq$73$69K>?_VX6S-V`j&kkC(;5~}5P=-i0Fy1Ib3BYT^de^|=a_d)-o^oNzDADzPt)#+fh>~04C^ut!} zX(6}qjChq@>dupb%tl*f8lZF;OT2g=3wF1>fz;g|a0lCjj! z!Rk?0h-8MCgJ>1BU_yH$$miUJS{YO?w%{r|V4M`LAx?zYWPJpA!a#oG270QHu<)Fn zg~R&Z;GWjY*M;S+@>uF-W@CwGxtm)|mLTRE*24mK)~8)fuGWd!p6W>42I!iID;}Vt zBCQH~K&oV9Z3!=^&iJkgxlD9K!0!kV4`iMuqB;s1lRtuUx&R80M`?H{Ha=WsiCD@A z8m}8@y)-h2+{g$4N3D~V1mWBaM_9g&k0fL34Fu1kC`K?CU5@=om=Nd7Np6d<|9>2|Cs%GVBcU9;#Nwt>7AcR#~O$0>amZ5GmB3VXv{? z@FIE~^J-*N#Abc-1;mk7@HnEOPe4z}5?84G2qYmOMR4@SN0=G$15^j*zvX4<9IX%{ zle0ycs$!lpM4xFemYJi>dO~FeQ9zLeB_F)(pr!$QGZ3y(aD%N88LkO{NJRnImD&hU z3Dw*Mqm0in^+3yc*KEwt|LI3selB-IKJJJ!1)3@Rz zo}(iH4mhC@D5XADLIiay*!LQ7WTT4=TPv1JRjD5MZ~yQAD}4Xr(IfshxkW{FnlgW| zSKQpFW6z3ST3-(Jr4HuOd4nPjLMdq{jhb^ns0=@7-wyd2(I0t{oa4_ZTKUDG?Pl@u zoK--GOe>gxBZ#{zIRcL)`6hm6na2P9tN&R0|4^cl|4jz;RP_|$$CYG8bw+FiB!u*UR8x&xC+HVJ27yY0Z6l$A=0{)`NbE&ivp!-S} zEmJ_8+Ysu>0ov%ZaHKmDGq#N!kDyu@ayl?WD*=` zu5PN_{zD!4&##VrwNS0Z_^<>?24Qs4?P&}firA0fjfJlhFK)rHA3frKlj~|fzMW)@O!q;$o;C!*OuhKp6vJ6P2klaKo57#X zJh&p@RMp*I&22K%h98Q%OB=;;ShG3>tVQd|;NrOY{I}^#Xu`{?jjI1Vly(=>QzA_5 z552UzC3k~FyIMY4g@WXn>R`G9c*1nCOp^^mge};MhC3V3402|7QR@buw69@#q20ta zsYQ%Y2w~}z0gH$f!*l!qeowVKavIqAQ7%l%S>SsnCTmU+Y0agEK@TL=h{3 z@ew*Sir!iwQBZcYhrsw>0>!*Y7Z!EM-9a!zjXUw8o?Whh|wf@8ptEdm-Gb zP4k&DZUr$+#5E_}ATSVh>!nK~!kG{b!Bb@gOJIb&X>+H*o2|WXkLQ~g&Idcoa<^Z; zW`gk$IDu8qFn8W<><%#FB5XTi^7P?#mnG$4TOIaLAnp9d#igH2(2hgeXytBN%%p^O zCS)UIAlg*+;A2Mr4>ng0Z6OSfcdlG zdFQXAU!O>Pg#|n5qO1zh00uHwIR&W*jM34ES%%|O|Mp27l0))EAOm;cV_=}uA%8>q z4#H<9k12NWOHf)QnMhE50<(e6@pvbo6-rLLb=>JJJ0OD+=SqEIGOC}|J10jcXgcM} z4kS);3pz5lON`U%9@sbS8w^;7p;N+&n38y>rP3&WGsfL|q0&!Kd{kCaD0Ss-O)3!k z@y^}x$q<}O+qNvGnY@N$0a`-6qF55*6xAr(yhd8XmK#&A4Bv>qa$X8Y*krYNEtz#A zG-q+{>`0$g31yo0xOHvr9FAJdoxgF7*L3ReD2xljvHU~j7w`o_03eTr4-}zU0K42h znHWDIUXPqcWfuwDW(D|&>CCo0#>?EesY$LP5)@>=Aj+E9!l*zNT<^cbs^Bx?&@RrD zu$*y$gE4NuEVG^kH@JLO`!ZIoPP_!vXIt_)Y3z+aopr^6mPj$i9FR;QJR- z4eE&CWKwb6;SV4%JE4^80XD%Qjcc6oEP%*))5Zuo+hh=^ge`Fp5>v;8ZgLpLLJmKCQ z9I1`x-qYb$YN>OB>zpy!TV`}(p8*PwUH05y96@4^xJ!xib3xwBTIUAY`C@NkozbD) zfApQO?zurZ0>vEh*ZOjQE+{;1xpRZ>e6cva)adl?KO#?F`rKe0L1T`%Z1w9u7hE2< z+_}MbzPOxTYIJ({AD1UDeQvOhpfN{Wwt86iULa1ab8ZlwFZM=jj1KDlqwSbA&kec} z80LttNM~VBu+N3|j$7{B;5%RJO)oV%z59>Elb1d>SVz#9BQB%ZDO|(-tIq|Q$F6s7 z5S}kKXVw}W;QdGEYt}wDXh-0fBR-?)ixeXKT=049dglh=`QmeCtvj58Y1O+7ba!FA;Ev zTGe#S?{-_#krQ!SqYI=gAl3mn=5gPn!nL9)77^2O})G!%`eBAPiF)8KOLpt8i(f-a5!EwWvG_Xubz> z-C=P&PFt4^Cc#kn)CFM8X^r_?#u!cv+K3mbQI)B9y(nyJ9ubEV;EW{BTLd3Y+JTFY zbZ8*4q3K6}&r|bY#3860H@SqyJeOVwjX@P+E=}-6QGSnp}xX zf^Y$Crdp>$V!2L(-zNpt!l8spX!jmIUaY{Uz@MG{gL{ZHX`p-zOu3(sKxgGoNnUmj zzsogHPXHmuT9W@BQI<4lJ_eH9XL$I51)qYHaQ=IUCK<4N3_Q7~uy8JWW}bXXvSRB% zEIVqw-9O4Q5lkNgb?!NApxUz}fBsWY7@Ip7Aiq_L=CzPF!~7YD%J)FjO@QWOpvpam zM=Ge|Q(%lO;U3bMalrW)ICFm?;({4I1)hjmpRN7wk$jtg$HGy=Yjk-}$f;3uX%uzD z?f|IR*1y@_*p+fek>!xxn5B2qX0Y9B!4~cYaye`^%||ncjNevX$~W9>Ho7L)^vhlk z6=tQ=5vm3fRzaKnM&lhLUEH!yGetd@nS<(DAuQf1Gyw=)DstFiM6=^CH^D8c$tN5I z%gf6&pCKb3JpqyT-e+e5skOlwL|#B)3{=)LuaKN^)2x+hYWM^prohNu6qOyE2>PEGi zd2hI=>??4urB{22wC52Dmxky^)ymdp-hK7z#jB&&`-iVy9~|!P9KCw+;_y?`8uVOy z3uoa`w*LHd$9kaSB${b99g&S%iAJa$HNONU?xW48pT_*jkb4-`&*w#NIMy7AjtmD} zSE@pO<&hdt2DBd@YFCySY0d6$zW(j^>wD{4-+pS0lnWWAsQwsayoUWP9}H18N-HJ! z_uKJ#pB6OFP-EC5FyE3k03EG-ioQPPuFHF109RIB=>pLUpjc=`F>ioi=v z2fqqDE4~lGr@2hjcF<@N_LL;~5Yl2qDZ>};2ZI)hcq1pc?v%z$DI}`WElQH(P1Iv~ z8`O2tRz>ww92tlQm5zuU$5Ob!A(#Ikib#Qs62iAthDr(K|g=XP*cbs}EAU%P7&n!&h+DPyF~ z$r$6;$FaB^37&%F<3gWqjR3ls+eiCN3K*KSCL*&7s0%3mNOV^uY)`vRjfA>U2ApM; z7VUM*HM+WTsQV|Ov(_hj%YL2MD4S>|?`TCtcIoL3*#?tbjs zsCDtLi0{oFs`?^rPnt)O5(lJZxq zm!=PxMzX7YYvVrHUxxMJARoxiSZxh9r_P{nt7vXJ=K-i zx{>JRZCZ{31S5)H4Wn}REcwTNlx_yLW`|XgU&-FkCJ2pRSzs0q@l$VGf@$2Wc4s}o z#Xw6e)bm|-+uIDD=``$(NG(ma>8v{dDo51akg`x4pj%zq_DcK9t(SW^5cJ$tr7yV! zJ5MZdmB-O;qG|M@8!%ynYV~j+Y}WXXwfqj;J9jmJYP_ z(>L{#clDLv6}mrR#Q=i|Q~ralZ{>5;3`TPfblB|&SiALH5R;LXIu?}0%}QNKsG}s` zqFGv3B8U5FL+N~)W1(>@HtSn51WN!Ah4Ev6h%MXHW{q~6Mh$|%&K6yMutz;l(TXo! zBP=;RG=a|Ox9H__QY{qJ1mLzerVOB#hGwl$g;_FO9M)YtaD@2&_dvB`p;WP@CC!nC z*8MBSuy_kGl5hgtG-*hUgS%2RLqSn|%3{A~Zc}J*j8<6|POBiI6&bz2x+ul0$omcQrXDaX z16l#M8(va^1BUX(4qj z_IYl?JC0L`~&V8xT$eDG5 zAkt7dMa4=U!`v6hK{IP(75D34=gVBf$YC!Z90NA4q2w`H zaUBjXU50Wjp_S+Kw+OqytprW&m~iB=j_=UOojkUG#VcEH_Im@!I-}08t@WE*VBv!x zm$RPZl!9y_gzTWxK0O=4lGQx$kWK&)|KTEz&XIC2!43Jf-iB2gJ00{e92#7bju?>g2-EST#Jr)0gnV!T5-!=@9YTPU_(7C)G|keIypc zx*oW&6_Dz8pok4geh~5Oq~Bxrgh6kF96BCgoxA|Hd~q*{OcuWmaCRZ6vqyRZ@x$zJ z3G;BLjWZHF#W>msOD6zuhHV=73FT%7omj!tw;a502CMY7#rc41F*-e-eJSmx{ zp?w6h5cD4NglQ*Y$yxaaAFB&dP8B!_CWEE|8V74!+NvrzDD1yB1Yxy}%W zDebAhjTSmC$>efLkkSqUil?Cr;1-Qe4nXsM^UM$WNS{I6NxCtfF0w=$ zkv*wJ&oQ|cZG9#C+-O&7=uJDpr9J@sT&@E+}XBHELrIDaXxB{sd_?5{wV&sX{ zTMuFfV2!$AV>be1`-CF_4n3zfUxDrpm}klGkUARioQ{y^-hu51*7JHFX@Zb%07ZKW z-731LBRo!4!wX0>QmMqOM37~qI|n!rIJnw~IDo7iizgX!?HqSWT7qXg*-KujRo0Wh zhSCKNmxOo5jsO+M9Z5o6SvDf3gE&)~E{5-{3SWcWNKHNRv~aVNb{{eX&FQ4F#6H^X zgk9rz^j(K3rF{{i>pH}CTU?O33$VF>&m-$yWPpE^)+Iyq`_StTg!Deb?I81|uiZ2E z$?AYyeOxzOCK-otjM_Qr_TmLR19sCYHfRq=f>J2@3H zi*;*~`wINQDw`t^1m(mn&<2JZsIVe%F;NHbBHtD~F_F&2A>dUCWCC`1MSu$;LYNyN z!gkvdK0=}b_`?9`^y~iRQuqf=O8#O zphsf_(*x|Hkv@l`7WqR+jhmC2zn(l#Rl9zQ#e!|_$v`*~qa<5BTyH!R8`>k=MwU51 z&OZx%>xMf$=ehhXD#Y%7i=Ydb4+nt7e6jA67pAdig^-Gf&aAdgH3@qVA zZJ`PTOi;9j367}>Oew?GYitFk(^9!ot*xzZ6vq9u_2u@Cyy3RI5IeM)p`Y#O(pB6R z+|y%BuX(HqnUG=s+vI`Vp1&P}kOIhHDuM^mO@^=pt1nyY$%|%Vs=#rIfhQ0`4}?$vG;rbJ zM0Vu~!Y;5kUC<~F;PFGF;!QYH zx;;=XW5%6c@11&5D8_6CK1_mNM>>*<7sv4@?pTj+#Sg0aVxegKAmd)inn|hl-heN& zTwbV{Kmz=oS;skpkqg*3o06l-Jbe{tUx6_cz%pMnT1vjrJ;A*xXb#zpppg~G`e5FOTsz>*kkoPGFf=53h+@co?DHPQ z*RBueFWkeuF8sie_0iZh0nqP3pn;z_k#j1!eAy>ug^ zIj8~G>jP5^ZJObQRI}2daX64ZJ0ti!@Iw$XVOu|x`X-mWivbq5zrDMfD z9r4&5vab$^EaOl|pBn>Y88iXq-e^dfY7t<*GtHm`HY>@neF0W99MPIYA3l^D4`BtU zKvByqQhS5SsyMSci~{Wrt&ov!1qMOklok3SvLMkFIC`Kv)D!rNz*&h1dSbEqwU6ob zG3CZsSof5&4X)(CtardYmH8UVo+BTEA`7HvcF@#i^GdqF2=DU7B*}2b0Rr5v3E4rE zb0u+Y;AOlaj}~o_HxpdCUMDA*J6P`c1sb|p{yRd-++K8L0t>@U&ktgpQikkOErX{C_1=X9h+Dg?7&>3WV+^`j`~8-;_c%n z&+UU{K|4mdJ$lk9K=hhsX4i|9va5M}#Nn#mOHH1G##^NoC&3tS(p;eB1KCNEuWgb6 zK;$BRqUEVQ#rM^CMr}+N0;L7$&Uwxe%0faS7JN7!24R*m82A#T0nkAdVU!GGHq)_6 z%S$ZT>SdD5o9;&chcerhR8P5S5yqIvv27BS8*&im5X82T(*n6WB*- z0zfoO_w12rYb4)`q;}9^h;sv+zQN9^djkyAhuWBgQbwto4no|zImrM5ogiWmg2xHk zd!3!>JCR^9UM!DABN}a|GUO09e#+U|6wv{9&}Udw@Zf;fe$~2Q=`!)wbEia*7nhsO z1{Z<2b3w-kuvOwFImfo0M8p&&h(~8lVT0Y&X#I_lV5PS&IK~yu<0{BM1~EyOhCAq3 zW%kVntd%ej>?OqW-<~899Y7~&m zCKxJ@fy4;m;)MX#jZiHKMg6zJ3BOn%U?3vG`^Em@i-Q*i%oL7fjf5PPD@g)BBLmF@c-{n#?Zh9> zy=s zlP#Dc-Cl8sswGOm^+;mSS48?UkxkSH`Uxq=fR3>i1f(Dp1iK&*y)H?LH~g-8$u}i9 zMr`MxI9kFPh?R5(>r)DrXR>2|PIsFY}r9*j=aNwOL2(l*kAGkh347I-tQVLjJ? z`I3##pYZWWdW4|ExFR^de}MH4HS8fJ{}`O%-nXDPAOH#S_bKa1!!$>}!|Sekj8o`j zB8^FOdCg+wgf|PpXljiRI}smLS$Ys&)ak%7uj1L&1^jc_+r0e4QlXH;-|DXXe;MxK zrIjG_VP)w@=Y71W4OigQh@6eCnw}!oqVYiqae8cR#qKI2SUOjg6n2YxhEmm57|i_#(~IBM+B= zRuRj@Cfp&Su&e_uP#GqlCE&WS{QElOz+3cQnB{J6nMJ^1J#2+%eOdtJYMq#stloyP z6J9yEln3n-DNv&ar0P)C>hXe#m+wT8n?;ui0umwOfy~pGRS%Ruf^)iP6p%+`aGBQ< zS6QIvAQm})UpGeG;b;mtp43sJJY@}-n;3%S>-fQAXT8D}L{Vsk4V)bU4f63|@i}UAguqUrm4R3k$VrWJS8b&B?+OR?32nC5FW4@vpi0wpIV5>yp@tMro?bVwBkYKO(76xNkwc7@c(6iwMs@-iu@Pw%a z5iGVt-CYvQ6G3?W9(1-SF+id#8Em13zs$-j`3e%9ip5e+tesFXwwFzF*2Pt z9D~Qh5{h@U+M{!r-hn*t&&@NNFiV)k9`+d;>Dx!(@B-#Dz=PC9m9-m`++=X;xPlgA zIf>_zNsu16%cQ*wFQBOD2x0{G!h}7#$dJckxm5k)R z@K5Kj&O5IU|NPOP{L8=oGYmt+4$ODEHb$@~;Xi{fh#H&b^BsJFKxu@7HwPh&Xq3Mo z3x*$#nBT-`YL&>&Vfw{2j^wk}6BJmvs`uah?e<$Np8rkW)W#H>f^!FHH(I49 z|8~&pMmzgiP<=^4V3sxm{gqPIQe)Kav=Sf5$1WNW-z?d!+6>n7Wx(`cf9vJJ*DnrN zNINf(9E3d3r~P)YbP+dzq1|k>*OAF0XF%PrBLv(2uBQ|Y_z2~ z)RIpT2Dw57e-Df6o8|S*Vl}^3Tw7mXU;Ey@;YPyq-m$o0{SW0})FW-(ukg+f5nT8+ z|HPx{@B05sOyjZwPKl}fhxqf76u&wj;Gs%UQ#jI(c!%MCwFDl**zxO!r~Dn4SsuFs zf6(!}@t;_dGKwLQf)@7p$o+@>pXmvT>XPEErO2xvnU7yu;C$c15`PH)=OryqF~#&! z50(?Vm1oY-AODw$-~KpxuUM3;^v8*|H{ZN5)A*Y=@brRMl}m5l4Bj_|E#cw#swL(g zKf{uB1i;Xf&&NZgwaR*V>@IG=q$%-rZ8~&y)y1ZqrDTasKAiaTq`kyVrfv(aVr?p5 zSZ{EP1XFo5V&Q#Z@qXM&$no4oHS!Sd))7^{NM7HvD zqUZaV|`xu>UMvr(DpM2#6~%#=#>l=r_} z+L(@r-AQFD7uPg?`nICP9jHxd0$sZUx%q>k27f?e%@_k0oDCnvz%`}CW;Pl#35_S% z=w>7`(^0Z%X-uIw9gVrmt>384|K87FMXye`<4;6cA|tlM;fzNqpHwd)w0}6Ft$#_n zp>5Nw?|dsPxs7DFA)M-b4BlG#D0!g&ha*AH|sp?;A;9F zKhGG=nNv?|>n?6gX@;Ki3c;r|L81Bl*jWcd6GJp`!PM%OlQ4x`xL(*OmfyUQg7mb6t52MEDnxhqkq9|htr(7*)66CR$&aP~ zRSVNu6Q*|xu1~O;Ot=QKS(v61Ri>vW(*fxY!e6C0LA$&I>H0*HnF|uI*rD;~?X${E ze8X409*dVef4;p~ZBGQj-47S64L_dqxn<6ao4-t2vUQ_x-fT+>D(dpGc|rK*jS!SK zZ@${zH62mN&h)fl%CLu8X#x_CKSRg5ru3yvX+@t=Eu8M=PEX#ZgVb!)Z8||>O6s;g zWw6v8h}-)7#j;OC+wQ*t5Sh>OFRP_usZh%+ZE|we3YVD+ffS2k? zty(R#T5EMkE#7;PGd~Zy#5~zS{`IikVL8l?pe3wL>873%?I#X@2Sz)Ck!6ymay_NJ zKImuuk&2%H-BTRWlcCp8tP(-wWTq#(+o<5<_G<2SRBfXb9HSu+xW>7Oi5>|wFyqE1<;uZ8@U6S znL!~bO-HsrS3(x4xxsd?kJ7J_Q+gkSjPZEo>eUPf3s~ zQ<{bDAo#6KIFbw=-d^sTfgn$a1sad?&J_Q#4Ma|XnwjYQQ3;kad69`axA7sn=cXrF zvq_TWjp;P8=}kye2BOU-MNa1@nwDr)C&=`7ASIuxq7Q6r$Dp)mXb_ zT>5ZQ*)|Z1_Iu>(jeXq_8cb2|;)&AwdUc~vs&0%IxrO+!Am(6*hbtT9wNkk@sdU;6 zn@rKRC6u6l$JE0gGVhId>_j_1YO$L(-kcmyvou5-iw+*CmaDZ&rBGfgmd5XJiRIw& zU4A99Pqz-sr7@dM05pA1TD>N~j;@_Y@8tjh;w(sRRhSLw7HIQ@x|d<=2xWNXv?c+> zdz5WXh{F>f#p0sz%9Zu%1Q?@F#_-4uw#M>wV?uhyAi&bVI#=GL-+zq#O{5}NrMJCG zsWgsrjoY20#M+r{?CHw=@=jz?hgU3CZgX}xxQ#LP?QxsCB|H8oCs!!mW^*-UEsx=F z<2H9&IpAaLu2#6!wJQoQ%xb>lws#A^&BxeTwN$;9@;Hi8EP`vVRkLoLaeKR^%jje5 zueeq%-v%+u6%_I-XG4a@ZSN-G@uTdkSgWnwW@8|fmGyBYFp~0PYM)EZi_utO8HrG1 zzg1C1?ujY&Y^w)w}2#K@;8RH~>yj@po=Y87?JCzz2Fq6tSx9Rokg ziX;4V$*o-qYrG2CZhLNv&n$~GCZR8%WbyBY#eO6Gvk$Ji%{>T8NXL9wG6CuR`6GpL z^DJz>Yj@{)1Ix8)rB=ozEWk*)F~QD}!Sv}bpyKq_AV%unjKWd44T1vAqW^&59(MD` zKT-_eM!V2C@Rbb0&I_bZ5f2q?qti@y-&gs(cY6OX6&8t_1EZwAuyqJYZC7XtqUuX*vp$49;d)DRw|D0)|*N-hj}cFgu|ylQS2 z_G2x056#37SAfo9_gZH8a@2XZ2(DCJUn|y1&~i35YPWV8POY-1kYwH)fn9NSl22h4uJY|{1z zgYg7M3xUHw9-3r`8^8Y}HK%=s^kb_(Y@fi@v}ZkscY2p-vQ%%~-QHF#m5apYdB_=dk48jOyrcKSY&jaCgKt%$wL{F4(+? zn~)5{VEC)%Mm83<;IDxg&jvk24IyO5ILrNC^&sps^qYl$2ls!qr~Qj241L{D;-Unnlb&VlBS-?GA$JMi+~i<7K@+ z2w!*KhkXjgPN1JFpq`KF-`+HQV!|Jj=IN!;#jq_QdRa4pABb2gZj{GFu`Ug+2Iw^f zFA5&mNQSP)YP0@i_^=c<89^9Nw*>ewagkwy#e5M>xHZGTJx{^#XfQq8oC6JS#&y&=8v^Zk|*M_04+NDs0w@>-EizwNl!~uv9FqVE_z~2HWOlF+Rs1wpeI1^tx`!rzZV`W80>L@}4V zx){ga56@G5g;hIlAGUq@L5>?@qq|s!-_dUhb4uPkw*+@A>D;tF}L06AM4p zG{O`P3gwB=(#I3Kcd6&w-ILzJk6!T)uxTKiL00e)N}*9AwZP3P_&oh98EjoW;oWs%0mvzCQf(M}P7!|N76($-~vA z7!LX?RhB_Wth~+OPiG!n(eLP@eGzt`a-=8w)fmA1W^R)iFUwz@cOnSpa=9;B;h@=X zgJJi&o54$4S^$z67{CL$ii0mKYpK^CYyyLF0azV>;2#JgofeUs@n`wymf5%O>zz@E zZ-4$dIMVO(6c2EV&o6>sesTEKhVs}Ck520C4(NjBc*;blVXu9Wo@&q=^-&N5gw|#m z*88X7@W?I2zQ?=n0j&Q5Mv8VQ>(_=>Gw@QMm*FS}Q{3ltwzp2~pz%32P2xVLbnS8YVLl5VhJzpO_ z6A#&cXu&7lN373zn7Y7rKkI{hj7P~U96!+=oj1b%O;_TEX(l1)q)Gkf^WM#!h|pu_ zPl9>kUQ>_VVZ*7B{9X9hGP&z(Ub@xRPy4-h?tI%PAob1RhrF?m|27Z8JM1-ko#5~P zK3GQn?NNzC1JVTl3dc^&&15B2OFbJB`>#~^55nCAN zDe466K~N9)D~ewCuXNC0gd}h_I6muj@b6g|Tu|9=1#XOhuX;RU>7RD?5BM!cz<^Ek zt?Psk8ijrGed0}!|2ugv_}ibqd+};#bMm5u6@sw}KaSuzo-GQHZU%Mm@BUrD!}$N% zdzb@*DUL{RE!*`_@|foPBTr0)#+{SuK^aL;~mR zpS9QjT6--_`u8y?{yv7q-zzZw+usL07(p{07I@+8_=tn{-}vB301As5aw_Pz0bE7m zjbPXhuA+5}eg$)s(1pl_-aZOC@*BZ~>-Qqg@k2WT9W^6D@FE-;tp6rH0bTD!c$qvJ zpZMPd=cCc(aQo@gv(D&z+{oiRo(?aYmCf4Iqr+Vs)zbzXOiwSM@I`~C!$I>Y&*D6u z#Jzs`_AGza&!hZ-Khi}fdV9t<{s!OYun8zIC_s>TJL=`HI&Yy!wK`!Q^!Jp%J$=y` zj!ydR6RhH75W%6}Iw9EH>$?B#;19VNy%3lXyy3sU558Y7u5SnHJL?<4dWkA|wfC(IA}cz?>ik(tva~M_U&&@my11Pkg}tok#j9PuURDt4hRU*_y?r^1vaV?V zrF&A=boBabc}>={bNmt``tz1$X$L#D?6NHGD*;_umbAO4`z`B|YBHEC=$Sk0iY)19 z|KKZrS&=opIus~XWKBDVI8T4piY)D!?6snhI{NatK(ZnW+CSRcHF#BINv~fUEGx3A z1AH%&$*O?h?qOZom%9XsKVwzFhS$n`uPTe=DCNVQ*E=ueGg<5Liz5MgRiXEC|K*W+6_7-*`px?SCOO;$t}VQa4$;Pwsa)2Wp%i;T=E$IpF|LM6fgi=)zE&f&3{c>mjh47tHRhG@)m7=P$ z+?@kZNF=nFhiRX9(Ic;dFRBmOtrXY%wGo(7q8xQPE^>-MAS;AuaFC{n<^e~29i>i~8a{)X;0 z^oaqLvH|>lY+W2%$vmX(0LC%Dg^HWFIo6-y!>1f8xH^w|qRWWy0%mLn_y6el%YTNq zg5dZZiXHw^P2o`b7JO3!c+}c> zS1?B7T1GH~N9WxKE@Mhvm1#%kc&pcUYwQLwFfc8bDUKFdY`loe{^gjJ8sbUXoxu=# z7q^~_&*eZViBMcCe$aWT3=Xdix~3`9KZISHZz#{xh~C4WL;nK=b+MK!RN?oro=Tsr9wgMk=J`p#*S&@s|DLL0`b?i=N!|XL zElGA~1KOJD>OtOzo+Y2OuQ!4|<5iuXd7K#JT_-~H;VkI%pvCezeh>`|5S#{T?pVCn zEq*@?uAp!B$D<(ZC5Mxm8&d$<16>FV1w7b@s0hWp~eJHTZg2<*V|CBk-@vpEJT%R4ay^ekjYbYBHwg8<|PhyC`5 z!Qg4v0t6%W#AZ@9#6^2M8jy1U7V*gk=i%igI7f>Q z@l$VGu&{vK*lbVEwcYQJdi@b8(rs@$*w<;Aa2IkNvQ5EyBC=qO?M6&jFcta~rQusZ z%-=bDi35S{rc{*P0tkjH!UCUK;zS<&)15qH3AE{8iwCVf4g_lpn&%;6GCX3z0t`!z ziD7_AXXiBg#srQ=goi=5^EL{;3fphPjo>v5EIobmO#2TG$IbHq(0GAeAu4-LXkqOZ z0u}HmR}qw*f$ipNFay(ZsSb&Qf6`2fpXiWpqigg}a!;A;27W^;2%yrrJ6~z;^`_Us zW`mC0=LQ}Dr->y1h{E_WKt#gTy2DQlZ8@o(?Y5kco~OKb)gQx)0W6f$>$GIkd?9Ak z^{~>e77Dsjw>|FRE;e|KaZ{M@Z6QGt&JIeu3a^0)BmO@zYDhN@Ey~z{79da`rgPT{ZB##OdC^i9L6F(x<4H%EE`pJh77O?Sgvpyg{GTM(9gb?UC zxM~)zj${Ok4z3otz5~#Ht*H(Zz~xDMXI*35I5%jPVrff)v)CFIWt=?y;VgdsobjHa z$zMp8Gl6g~x&r%b0Ygc#P>>LXybgZHBmG0}cN`fZBm6|pA}JPs;Jo;DTLlMxo2DI1 zr$QTU0-WRFsDELf>B!DcbCRaY6!ATy0McX-VMAD^Xe4-im$Ly7=>Irzpz;t=jLP;Z@K9IZ(y6FuyBfvQ1l-+Rt@o+45MzRjbUyT0KxF<(1 zS}C+C#z}46Dvs?V@>37U{?S~WWd^I!3hfmx9d{1q?VT6BUrf3J~@@! z_ypkmtq1#_x~saEK@K{a2}uo=I=E5FoKx!k(0^N` zA1IPn=eThoijgR#CW{>pL3A+{N;8dZ>LGOdy|b7vdAQ+X#pws1)B7(w|bgeSB;I0+mo1NsrviJ1LhYXsds6ZF86GF-G+Em})n zZ?Ar^&yU;PwCx3PPs~g;+T(Z&yr$_?%y;WfJ>)e4;a4P;Qq!tGcTEZgq;u zbC$Q@xnLEZTk9AoV`R&Nah%a#sv)U5nFtMWaH;2rRxa3|TFwG+@&TqtUc(X#yOL_> zPawiAgdIomCYCFvC1ol^l@yY(AyJ^UCoVH{wwV`+WX{=JV2}Dt6yGPBqGR{_XtN+5 zC&u|w$B(3td~+hXW|hX;F2H635|bBH~IT|ftb|03mm zq~wGg=#AE4bptUnD0;9HqrGH2JNH~xofX)+;rxt(Rc_|ML*97p*+rvl*mkPrUtM^4_)7*L>%RnRV7y3m&25(RXgyTN1ps^$ zGEcoy&ErPsR6bjUI@1=yrxR=rPwAfoaCIUAOcA9_NpN%cx7X_``vGLWU=BxB@E*wCqnFNrkDac=;Y8x6BIlzK1~6h z==g~T7b50u4_El<9SmW_4M)N+0rl_p4{cJQu&BnkLvf9tTGZ4;@LN)-X0Zq%XW_P0 zDOB9;)tQ=(&l0BRjjj@;uO&0}CO(z><8J1dZCzQ)%ji=27=F7f-qA|= z8BS1RK&yn%G4M))VjSP;O%BnJ!({H{{hfmy@42aqH-YqY2l>bpyW!K%aUY>SJlR2X zGEpz*$l1>2oL$Bbcnk~f{lnP$68|wB9~=%rq5!b@GPD zcHTKV$H_oXbCae{N*4gcLqZ+mJ&5+GJ7hR+=vN+>e~tq+RagT!{+MdS146+X;z7R3 zyv867dSb>p^qM!OXBAkmlHs-ilzXfNaqVUYE+O(pXkd^@bR0-*hWz<*+<*xWnrXM; zHIVNfGqnzhdHR)p!`!$hFcAjVv>0GQ3HN^Ap=eUE2k-u{gP1a;Ylyow>SgA24e`=< z!$yQ)nlNgHlEiIyg%GB&{^J+VfQ?4BYt4Rs{B|wNtG(T)h+)*fJQ2jZ2TX|CZC==g zVT4&VsN`&{#}T&i1d0bkkFnGujLphZNFpL+uVplK4;xPcrinO+1hY zg21@?4Izdg#VnjiAiWrN2-YO=k{+3(b3`8;;g^{X=xl%lsb!KVjO!<&BE!jxoC2q; z@mmXBn=32=WxYFpd4I$kt`D%Gg@EKIWt$Q!>aPkDS;c^rk%aIWppQ^fQ_#%)r|mQ@=>j_ksu8DrKq?zfpFM&{SHJ4 zLXogDu9)l)>=BRoXQ53&?;nll?`f8nz;){o{<6#Niuc?l0EaY}KdY0jRyuQhIHL$d z;w|pkd$Q3Y6Y`827ja~w2ZISzi991_?jV9BSz?1>@EEeHe-)HVBt*#t2#Tc|SUVDj z5LWV@OkCkHjY8z&B;n}`sR=L|gFFHp9^$KDA;IGxo;`a8N%}c-uwV%J2*pCk_|Icx ze?SVxL30}dLN{!{;DosfTM6kGg9x#)9zGG{osph)6d}Nyyont$XCKpp9DYDl>xY3p z{X-9L4=+`MA-bTJyBB!Ay1MeU4#763=EdikXe{?2aHpwWA}2qoTOUc?it!*;Z_{jZ zwZt7yLjA^*Vx~}z5uel4sti_UnSkkG%*>24@r2h)mRCGeVnL$GSfiB3{}p|zSX0G4 zeqPz5qdzB(lXvmFsNTp1MbNZ^;Otp|%dMUMlq??*;B=zbUxe&3s7I$xPiMZ-sYn0Zfcx?k>0vUCruDWuFnpWH%cZP@({%$|Ylis2 zsmmnQLmO&juJ|u>)El%Vw2m*jio%Q6oUFTLw9*8~aD@(48|_(S`Htgv7I zehp<#++T1h@7LnmkL$59g?c?WO*5vDLW^H!8B;G|dgT1%QED3qMK-xIyh^QnS@U6D zQeNgx0kKjiTSjkRXR@%(i8Fxs(L4;CIKX)UBfg&xP63;|J#;D}3KXJO8%!+7Il)$e z(MHD$UHY`(B=y-t(QkOQK@LkWs5t-{BvJ~9fXZgWAeXZw3PyizA%yI(3lG%@z89i1 za15z6-s>(OxWbKj z*kZrV!k6`9%%^ZQ3r@48pu5t)LFxjFz+wq<%;j zc`D9Iq>VL^_e5|zgBd%O1RG?E(tm{zl1t#uGdbB#4aXt}sk!F_m^h>Hv?jR7Co)9x z_MS^w#}r(X0u%evK@i)}0++P7Q1$}TBdNq?#V7e@>i0G7E6LZEm1VhGI6&kAB~E0G z`NxSW0H@WP!w{n@a-}fvQnBE+&}1yNraCAotKl3TMHjXYQg(M7yyt^eyz@98rW+wj zCZXT1p98O!&vXb*PnCBG)S|KZ2Tz1nSYF^x7g(OO31kS`J5b7-U(YO5pt(~LGWAAXPr zMN6FP?H?wM1_ zF1rS&gRUVFF=&jLNjO}i21KD^Ps2BwPkX6xB8WN|@0u8T+fMK_xYl&^LHHEF8vKylX9*Ls(E!1jffjRv`aIKp)$d9;7nZhPXZ?K5AKsP)p-kQmN=B zEqN)OW*sj6L&hv-_tmY8&x2i=18+0{z1}$rA(J_V5lSBN1zT%ETKxpRAItP z^cLt>lhbM-Eeo5bKMg%V2z|P9B+0umTK1s-7i+6VQ{}PO`!@ zyeRUNa@73l!lokMd`E=qBu$O5J%Qhz0|k27VNmJmRamH*x`oMXGBc z<{hV;6X<#_@FRg$QE~Q{IpV3(yKw=A!>rZ@uDCK(9ous_YSBLwF>Ou>EX3JPS~^lv zyEb6JP=IhGP&k6XAa5)}DbFpLuV>FRgr0vM`FEEbyMpi1mB3lGZ1|ElFCRnJ!DVRBRjj?=n5Z3{*gBrag-u5NJ>uY7@%aJU_M<%8Maf=PQIHfrq@ zqH0l5&mH1IJy|?`=dcb$y;S$RCv1#GHgONRhaAZ>lXS?=eCrZjI>YV2he`0e*Z@%l z;57Nf9qVb9FsCrvDm-XKW3~$fW@%H-!I!0&u)~9;4G0%#Tgrk^OPSYvhmtIX>~^(7 zCfznybgDQ$?^}%tQksH-({%hgTg*aGG@=CE|d{Q#lTsZ8haiAI2s}o z1_A*`f&y>BNrcqKnH7!SVY>lb)N>&9vZybR63lh7NQK>9AhWMgm`D|f%LZ_cwuea( z-d2^(^f&HO6~E#5k~xa1mIG?d=u(odbZAxWx?@}y76Zl_?54h`Lb4+= znxbw9HRMz|qmFnw84DzOilX39N1vMlWEnICWe@-rmb(D+2lEW7H?RgAu?u7OTm;uQ zIUQ_YfR$zq!Z4Kt2p?eus6f%!DM4di6+xgWVli5NSPdWo83KZALK5@@*3kJtK9cee zbjQ)+sx>4lpVbpfB$JVX*0m5$^}g28!0LU?-wV^O1$o&zG66SkR+SPR6#h7=oZ0j04hp%C~4 z^>U@UkU%$}H1#If=a03S#zye6!(bfd%h^_PM-g;oFqPcSn3`%2nb8^lp1z$rF4yZI z&B~`nz`dM2)u6Va_|vs&@22gDBWt4It}V|vuwz1b;!)r{0)4!YqnY5a%EewyoSSwq zP{+WO1XFnyFy`QR0=F`UZ`)zI=j@ww_3^z}YX>i8UOG2?&O7#)4ca4C(bvb!D75bAB#sc-cDl(Oi;>(B~Q7Cn<6^k4*m>xg}8*^ zN>{53ZY1UXffuWYAXbp!P!mlM7llb03Vo;(Q z7(`wC#fnNO#{o-0IX$?KXqdUsks&X-4M8k0nyt#^E1r0cksONzH-nJ-vl4;V5l{eeU%->GSerGlcTkdiz@eTp_49zpmk zdS@P&n3z5!w+7iu6NoJ7_4b)4HmIZbF;es68~RDW`!-9H697YNGqz|qFsPWp7kx>L{pOmqI2x0>s6FzO6;qtPBn3>Kx|UhDUq02T zxo5u21`fPTd%7X_ZKK zv`z_5#wBt{K;Nu1x`8go5&?9z|4anX2f>;ADxdCRe`3^${hH3%A(in(<_aarT*~TQ zGM5+;;wns@0LymeO1-+C0r#gO0vt%QlW@zV#e%6D$kQAkh>CnDtxO1M_>481H0ccy zTDUSap!wApD2cj4Vl6`R7p+8DvOo^-oM2i~sCRlPKEIt?n$R*T_A*5FYSN7I=W~1@ zjs$5hIa!87kUM1o>po^0*}_;#&QZ?ZV+5W`@f@UY3kL@DV!Kux2q-m>l#SpZ3?|NE z6d33r8hyV1>d4&;71kliG%q^6@p~|PtRXdKvRH?roIzNU^8#d*)!kPI$FGiF*)dPx zNVZxG*PZ1GD?y8OQUb?zMi=MufQu}#IA<$%OlhnD6nW}ac1n^*z2z1ZAh`s^gKz+G zgk*4V2sO!sSF<1Ez+4#O_TEl*5CCy|#UZM1N-Cs|rHmLZ|H0-nLowFpsPe(O$K_7i zUTS{!z##fPx=6g?_cZZkn=u1ifkea(cHfw-bqLv0sUAx>yVz9>h2<&~d@1|8Oj6m? z0uHR}4tR(lOYm}M*PqtrVGayT`92aV={Qp7i28qDKi>^D3zZU`w8Qb4hGw^eJ$hvO zDE~e}(*WwvtV3MSH4rpm39%=9JhoZY`N3S4?-4VI229uZF*pa^x8SW{bh3q#^RPG( z5Wsl}?y2|0d@ec>rBn}5m?6poilbOA{~^Cro!7jeDi5l@Ka6k-943|}3Y=eGB1<4k z%}CeJw(LaG{^W-hrtZ^I8sK)hv{~8?{_*>r-19&IV8zdp`+zdZS+y7BA3lgAyZ z+!YHrxRLznE-}gnKgKb6MDGzh=nl0FMfJrolJw_RJX61+MGx(O@gB%IYmZVdCJL_wGMR$*%O)5vrKrKQoQ1O)1;SEsv2+1i% zJkn3V|5yZsY%_7?XB3S$4b=Y`8${*`Lcmd5AE!aMGW{6K*YShL&S#D-h$E#HHP8qe zxkCeV_#L(w1DDRrR{zDjs;f`R3LWKg-6#*Rx>es?NRrHvX`D768IEeDX~g2^D%^1= zX|Rnz2Z|2xUGKe_WmNg{%=6-xZtqj8T26e(RUi)}(R?_-jpL{M>>1sboD$J@(d=Vs z0JWXy3Y3@RT0WCO$CqI<01~|H|Aa8rqkSiY+a}xIaxIn{yx8 z^Q#UaW>)OxGtS4|H;9=kmPx=eP^Mk+wuVb*p)muI z8+%al!C@DU55%saT%)EkiykrA74luWq(G%ZFJy!kWePZDB!&ok6?a^b?hG~BU7pHn zyRscS+nEBuF@GG9A^sgl~(>r-O zE_S>9F-w7Iz5oLWIB+kt4rsGGhRAPCnLHhp@)u~@GQL2-56JWGf(XI4d{>8Q>=EjV z&`F*6N8myQX)vu!O*D$cIYzD;E$&Fi?DDh-aeIN_l(a^W9*LxygCb@+%RV%C<#BwO z5o^VAsT#*{SpEzL=6sas1&H5f`6%^976US3!GZ9<#0v;_y8BBp9~lq2j)$;k1)h{# zUST2l&Ur?dZjK}xE|G|`OuG#?M5Euj&ii$;Z({Er9QDXpMkwM1eO1cAMC(;}huw@?VjWzgQN9!zL|3e68Mbbf3`ryjIzWcsePM;ER$ zNsq2XS&et^)iA$l+qXHJWB5jpMRd~%J?0Tf{=qpeAVFiuS{KDidGf%9mxz)@57hK! zStGZ+>9RoUg&B@1E~M?0nKnp@tq66eh0R>?6ff?+2~uG)9XGQSX%Lh}{)Gy;19JN|ooS*4Gq%GCRFYFy5gsWELk9+cqObQA;@%qSl&+QcT+p zBILoMpZH*wD3w|e_8z^mpew0h3b{=+oBA_+=z3w6u1&agL5SwBvpxt=Lfi;`)Xr(z z>6 zFU{yhlzbZ%3xmIfs(A(mG}K>EwI=?#(?ciHUQ53~UbXj|TxjWqU3&?woCfi40*EHGI1r$f z77WBScBN(Lk0bDV+u{#vZfhv7FbIBFv(2pmA~&qefe)|1p9eb$n_G6JsUYN z(uHTZGcx9&CbVZT)2jl0!tgIY-9JK6GyMDY;Q@kEgLf$Xl-TZh*MdCu?HLiI$QeO| z@I*UPqzQVeKClc?OLhH2#|;n0k~bx#!-uFH&O)MGLmqX*pE3$`CXwvnQ^!AZy148I z`S<6ei!Q=JN5(H<$sm;#9w{QHdmRbW$Mi}|54lM%sAR0XfPZcy7%1_QTM6X-wH(Z}J!G_+S_-hZpv7t^X`p7fq$i!HNn#s>r31J^~@A^Pqe*ZiGw1*}2sIa+Dk|!fPmdZb1|2d8d?= zEEI&gdV2ZhbT~YpECHxIS|hts!wX~=N2WwB$9`3zLsyP1D_G4%lvwm~k_$9KSPD`{ zjGRLcF|I6xWyFngg}5Ng^f#6gN#x5{+SWLAXC_`FimecqkH@V`IQ5$Nzs}{mTCUT) zz>m?WnSYY_rH^q8tAiUROHmUw1?so&d*P0fSS< z_7V`A1ug&#vzHFz4{oxT7%b3&O4LhO*Twg^Y9X??xSTnKairdBuvp~IFmFwOk14mb z%Wk|0lK5}cz#$1rDUMF-DT95Qe8W~pXLw7B`5=@}v^ljW^OqfzQNsl)Xj)K$(I(o& zu-&NBl6_9FWusdnSi%R{SbGmLg9EF|OAl*wDx08-Y=X%$ zyky6&LQs~%<%)Y&FtvCfs4uD4-^h1$34N3+C&&@Lv z4`yXtNh2jQ59Avc+2q3Iig9XqBZ8#&<`PRpiDxJolaf6P_6DpvD4#JbyvAyu>sLfx zR|liR>*FyPs8ZTx=8T@P&a7RRxwXvt)ipC0(#xRD`c6{i&}RurEzTzDD6q~eq9EoY z@Um2G^IPJ_?auLNn9KKB}sVg65A3x!u8aOUWhzsGtw(hEbX` z;%(n?&sk(J5Y)`fz5?tag8SpL92dGUpGQ#arqoy3d;R*=>ytMJ$FJWU9q&CmdHw3u zaeVf3`a)&tfW^dli)LCg#w@BWb5ut0ya?H?-9Sa_N33z9PCx&kN&1tAhcb<9^>Xpqb9a zflmf7^~v4tiAW_*K@W?mHhEpk&xW?5?s^qJ>e zQU3j9Gmk~ScgoRRF*ylhiC&~>Ct6vT_fJA{86i1&M6(6tBo#k&@i?(FnCKUGOx&De zl@u=H!30nerT_*bbfq^yh^VF`MKqm{;Fg5F_s1{)^j-aBedlW<$=lNNRBdA_LEpgf zKj|BY_BoH=1kO&;HEs>w=@Rufs%^wZ^IZuM+;D;4(I;ZH!6gJh$BU!5DAc@t;&iGCn0OIULtb|Y!(x1_thd9(j)gJnbz zAPWx7G4usKM4$$212MEX)(TG%qW9Pulw=qF6a$d8s@U!xArG>btPZk^xHJeI8aC`j z)M68t5Ju7A++e&Yk4ICY|X~F-sU0d5}p!eDs!cS7> zTuOq;>L><(#vlE3JRCfQm**)Wsd6?>MU;5dC+QTcDxaj&T}!7=mkODX=`Ms!+-vy2 zTdnI(ZP%Ns#)X4`-Cm?xBSKkSl&Pj-jxf!I1s0Ie*}3STa&%Vdo#Ypv)Cp(QeBu;$ z%_$7mK8YwP6ZlC)-J8jd9GA2Lds9xJ=G5F&)7LR&))rFUAIA?XrAjHKj}74zLI~!Q zM)nEa?+x8Y=j>gUDSrsBP`LGBk^kD_nFCZ`b3;9 zrzPrf@dHV72;wJ+ELIIje332z zI7Rhhw0thnbA;6C*mNsNO)M#!^kX91O@p%OZE)%_+dab_nk)h7bqLG&`x*U~$C` zWEMZ;uTqP-a59Wx(67dHrmDgi$(LA~OkUg{Vs-7ZetN zzsIdoX^0k=(Q(*sqR(8nI8hb-JkfmWqK~_gTAobdoB7z)=zqL(bnqk-5n)kxX(8e` z54J{h-j`c4NqS?f3>2%y+Lr9faYpPFcP>y)P&<|0YeAj~%T#l1KK#c0D{ntyer9CD z7yUllo4k0jn}UU0LQJ3eB5IlcS_%g~=ha}=i?c3kJQ`!5=2!E0Xl9YcdL^~GX{Amx z%UdSLK`zo-#ZXDnHl}DxHT;}N@;z^J-)Ywr5d4 z-(+?(w=f3-mI3iD6Hz&K=9FKuD;G-ZWS4_4z=V6FDYvv&a_q-fee_*p#Yc$$7K_AN zs6 zQq5Nj)vaPZ_%&S)h;YloYpS`i3^}vf*C6M#B#-B7PJ#muc%df03V`?>Jfc1J&m%hk z3q(Gwq)Onzs$YT$N0O9><~9toaW7tb@_{Qzxo-*-TnPsoR6PTCk*LoiuR+&@_F7=a zTuv8-H?N1%F$ynZ`i+46PH5Xt5yAad))C@^Oqp<()}gIHE`!Sgux@u*Pi_MjXZyWe zD_!M}XMqY{C^K_cRJDF6!z&x}T6l>iLm0(NPK4OklwW|(CH&Or^uTNnO`HMnH0zYI z&1v;=|C>o5@EKq(;g^8=cl(DnDNtCnViZ$FUq%=ifSyPsWXA}_L*UzwS-5SX5=J4W zkvW$H2u^fiqzC5?8P#i<;U+$n`(s*p^4685yp;$nThmlV^~Z74h_ZM`1LbF^`EwZ6 zGCbfIc*WrZj_*W|L$nR{uS2`gVIX&gljo)`-UQOqodK$3vRcN|&&OzQI6T=wp$%sQ z&Xuzry(<|P0nNZXe!yc`+pyYV!z-=#J>EZjSD}i9e`{9q$;l89W>(({%FHNg1M;>$96o>P!fo8<>Wo z$0$CI<}~Wdz?C8W$}^as;}}i%6`ux_J+}vEu#@|(P3Xu{WC0}(Vx@V_8&h)qRaJM* z%UD{^P+l zbyBcUVb||bSsm?rF$*UWNH2yR zf;I82Z0Jk8F=tL@Dv9`Qri+>6%{QEr+39SlThxiCSssejnJm3hgo7f{U9;utdg2*EG85V;to+6!SxkOES8iE2Qf-FAMA4n zVH;5S^af*TvpBjy^y-fGC1@@aIDIm$HPIW4{*xcbe z0G7Qe9W|JU+zxiS=*Be)_N3;@L`iaCk`J^(YP>d~*)+~fsf{|D{e8inmecv)k{uP( zOUne6r>t%nW?}&x7cZok2Cd zHuJi{M+BYR^%A$3t0Lr=3L&wXS_&y1_WHf+3n}e}FD^VQ6zrIF@Zk46<*48W8u*o8 z2t+o4(^5zHx2@z1cc?!X9ndggX(1wNSX=qj-sIm#7t)m*8V zD;1E?RoN<*HtU2 zPTU@T^{@WwzkhN1zyIU^`REb1OAn}S^ zJ->;*H9a8yQ+nJ_;A6p6>8BQEe~Rh_oi?lPUte_J9RJHl|Li~h(|>>#HtM4O{+^A& zrj6on*kkAN;b&?Wv8v!_91=DCw_%m(e0ee7kab{1kI@}~HDHIR?%F)3nS_E%(fgB8 zgv*<7eW>ANRY-^W8%(Wh9CN4X8WwTqz5o3A|MEXzhx~8$&bMx{^P#wcPSo7|Y1r?@ z+y6y)#u{1+_86McUuod2bz1m+Eo`^Sm3p(5D@4t$TxF|P%+(9kC|8eKrFOH@EL6&k zwGCrDc#H7jdk#kacUDlHU)S?xoYc|5&f(FQua33Y<*z!-8Z1}dfK9Jv?|piCvP4%z z3y*#uFM;3i&)T=&eE0U{&ws3Z`}4P>mtTDS)2pLG;nnfC?_V6BT^)S$X7uWduiw7B z`0l5JFJ4|9JUi&Tz;`b@h4(Li-mkv=`3;`kyLxq0DdXqr!LzsJm(O;7?`=nCS!$j? zmJhP?{QTOc799%EIUhI-=4br|e&!s#jGSpw-G`B~9H^u*`FMs0b>m|kSp?! z8In_5Lr^&NfzT!Oam{RU08HiOc%ZY#(`h-}!<(a7Pq`ssX)s^m2%;hyPCo3yw3)TZ zgqCiywVAJ%N(mVG9sgMFNqIBBS=CNm`uQx58KxBw8A8)FFuf#Xrsr7m^D(Ed&~5UI zSFgT!v6mKn)7iGA(h_#HO1@Ms=Zjm#{8rV2%o^jUc%V`#CktAWx^}BmnSRwt4+LS zAEwtDS3l#On z3x#~GP}r;&w!U*~i<)WdS@TriV!j9nrf2Z1mGpjyGDC#zg<+ZR$6veK6AcvqbF)=s zN7Jp9^a7aEnVy-SIE1}8yBOurnK4)N=jf;RC=@bHO_wjMT`?DAOgA_}(R=vkfKXe( zGuT#a6B!LA$Ra@;8AcnKa+D(A9Xtjaq4(bAX04nr)#|k;-ujecjn~_plV59tUJi%d zwa}zv@&O0m8DIOyy3l%DXUrR>q>Fk!n1UJmpDLk+UDx4a40(AE&}n%LfCzx49-_0Up>#F2`I1p51W?W9&o(}r@L zG)tty04oC?1~y9Kn?MCApXsk`$S!|9A>MMWu;ptKNP3Wp$9y%zQA$O}Nd(MIcrhRq zr#_lxKJp5ZD&%>eW6Bp7sOHw4X`$;SBu<2`+z|LZ7O_Rwpa`L=mcKJSsh8ijzx$$k zUjM21=jf+m?aRO8pWWvvHH!Bq&fp)$pc6;r76x%iwyA*p$Ip|V1a22?-CZ}7?Ik;&vaG#4NL4H7tXD*D>FL0L-(B zuQ{dW#uR{doGxZbmsk)bqo5m8BpDyWl;>jvDRPkaEv6-~pWX#i(=Eg#5Vy4eN#dk1 zn-8}N=^~L7K;BV6>t1P?h4N0oH1y!oe&zPG z8A&=-4IpoK&c>gH=22HGINDXRtd&2NI-Bur2x8NLLPq-~Eof8ba zco#7s-rQ!Vcf8nUvo)f*JI=fu1^~)G6X&1J3Ul*HInq3CG$6p0y;+on>J0^Y(_r<1 z^(9QvVBgJ=uw55-TX4;)K-mtLIe3Cr2XW`8H}e(v=Y2xf>!f3SdF=G{MVDwa7r^$o z;m!vvI=dqBe%pr2OHEI6%f;o@YH&9mW};u% zrDMd&>A3*gMTWOc;6Us6%xb8^jh@%4%yY@(HoLIiUyE$!);K<~Ze$t3Z9^~3VE#$W zW>!QFZzN)fZDQszta9adN3z_QBio4`P2$x`H#9sCOI2;anHY9i-C=1$mf`Q^n9LtM zmq3=?ij9A_d!cV^?hbB4;vA6oQRZ^1<*|xW+#Pw#2JV2kCs%zxq@CK$>IgftnR_Ga z)P`d1!im5SM5=ov>DBH72B>63qLu?4$0zr=5%EZwl4qvIlA2Q{g?Dvgfw#ES(YBJ6 zQgF`Yn#=NiCzV$RSlm!YLyqD6CC_H`R2SSZ1f?_LM9rsn8ipJk418=Vgjb@Qx&@#% zkmuc*uio9ft@L0w;>lg^0$pNpNvwl5mt>Inw>2j|NcZQrv7+#nF^T$eMjrSMPxlx7Jm-PQvkgh|k>m0EFJF=uV_ZvbLBv>FL=WGQW(nea&z*!X@*diVX%BO+5>OI~&lG}Ec#qN(_ zk6f^vdfc*pcG!Hr{I`)lE_T}@9td`)fx9Z~c6+>c?6!%Q#qN)w+@cl|vc5gbXa!t6 zGv-Ie_{l9k6x^R&*NT0XoL>4;8t%xZem`C7y@h2v#KvULjH?gWkXIXPyF(tnC4!)E!fx4j(7l zP0Q!JZLs9Gkyy@+e@M3TYu9H}YY5;n`T&>7k~`LD2973rcCXgmUOqmLk`Cf_m0Of9 z|8+DIX7;q+Dc-Oq$82NQ>Y#xT?urlk7kd3$x*o@V4!w4aEB=p%5sUv>QR0-R@5!Ph zE#O(vMQ#I)tJ)T)RV2V7g)%GQrq#L15K_$$4_dJSsnv*IXH^=Iwz%?+yQB?(ur;~B zT|8vT4cuYBJ)$R`jdrBFA_|g+J#<-=9Ck~nLO*eIFXttE?d;ybU88qw;Vc!R*-=0n z>B_fE4n{kkC`2A-#E!N&T=#%gZrIbtTtg(sH@obl`8movp`(xN4DY%IhJ!J?`2>BP z548`1z1^cgwwC`}w>ez0K{_{(AgT6Yo#3_QJur*FR)Anc=|YcD-3hSeikksQCi%^H zUh|92;XFg75?qwf77E_Bu!7KQK!>1Q8k+wF58s6X~gQa zNxSVvt~anK0qzVm0F1n}4A?n*i7p*X%bBu;+i$~-;B|z0SaQB_udq0^ z|Dfwd_5!;?h46Di3v0Lfb^;!)VsiVE6^(JH+d?}vDNNHfYH^tYlYLv4xm<$NvPu;) zRSIy-aF21vaF?YPq%K8VNFpwEAw2<<(m+Cpo?z*z@r0((X=pHmcgd z83n`3sEPZzO(};GYWXFclPm9&ZS#g^_GleVoC!<}1)KR=z7RYPFIu$ z{=OEL%2B;tZeHXZSjB#U4MN0H0TR4uH8fQm4 zv#anL1U=&a6KSQ|iCkbgcbn4EDOL+fL4+H3EwobWp;(UcC|1@Lbcqok-3Qs$*Cqg? zjUSQTeSk4r7RDd4gMpN#$DMp!k5U#MF9@Xy&rysgi^q=hrQkYUv04T0e2p9MtQ+7< z2X|jGE(ruOLXG}GvlKVVBk5XG1uWDAa{9wrV)^;h0zkd!3M>Lm5`>@fdQ)_E9sG_* z`iI=_I5IRT{6qmEWl;aXdGYPG%76Sep{?Ff|Hp zFf=SvuFhwG$db(OQD1~Y!)BgXaZ4t9oG{b->_yLR3+{08a4<0Ayn3Jchun>F3>VGv0;$Qd1ed^5>__@WQX0( z+4%_VW!1Eys^+a;-jf}ucF~QXJyX9x(Q{tZ!m3+8afuj7SZebeo$KPg8#A*dYYRP3 zbg^u8A!cRrl!qiy}!vR7OOv=xTYMs1}Ewl10B~$~wbt0f#7&K8t4Fgf8V;rp= ztrK)mG@h;C#ZGB<`y$kL9K7d)l}ZxN2a+{FiFXw8ZK8UbXYBAaaI0}D1ii;Ro5-nH za#sGqCstn^HGpJ*t?1^%CY-$}v$i4{HvyXnv1BBk%)_$K3XZ38Jb4!TJyqNRAn>{v zN7(n!fGBrWTP^t#J9B8HcCf9^UG_EGPwP4^%K}rSsa9&Q98>SJOHSb>!4cQcRABfj zq8vS0Wdl5k$LG_hS&;fxurGF|pg4)Qj=c7t99 z0M>Zd#L(Mzf~Uc?Dy;Ob7!ySEX6%j}w;!`XqT)Mvj(D&Di^?thAY2FsEAIeB@runv zk^-tI3&xWoL&)!O^S9xk;O#vIoo{FA{|TYUvWiX5Dt#+AOH(W3bzF-&44`t z^s&^oSqZ5OwuNKR4V+_m2An00XZ_ZM0tgW(WiJi$K0v40w@O_)EnJ>(laY%-UYX+! zt|8yN^&oZ>Z`j0*09ipGBT*%C6}+y&cZWk*gLnwqF%W6o9}l~50ixnUIB22Kit%uH z3ccxjXJb50fk6T!KB!h=&ORtvB4^>xg9KMrp>`Hlj=y9>t^>jzwT@u_Sr+V-TBV)_ zwsMd;Gz}BS9ZAYuSywJ+Y=|CYdPH?Gd}nGsWLE0alEJJ;%i6%iKHA|TuJQXd$$z3) zFqPRf&cbyDvT2$Q@DEf%z#lKzT^7)QI^ulB zd82RGK_OI89qH1gFP_GFyaHD5Rqtt5F;!OW^i)V-tEVgU3jDz;n`1BpmBcOZ2Kc;8 zSrNFHs$->|1y4++Q@%(z`~t^ z3~-xxcpT-=^3Y9a=~H*!2&By&e}o&7u(V0Z1soQsu5oSRKnBNydM-`yF;F0)KmIaD zJXI9z?q7i6u*9&t!QjkF9<}HnsX1x+>&bH^+6BTIVYhK_ynm&76twcb7LZQjC9!WK zD;%KbpGUrT!|5P**p2o}y4W8>*1>8KKx4D`1cuXDG`NIZA3fpW48kiD$AAaic2Z9p zKemwd0sjtNO=@+CeMu2+yw!L%4DM37!p^K)g=s(Se7^fE#i8%S$!k8|{bxK?tDdbK zM>+cBny30_37H|(&t-+jam=yPCAp!AurG-6aWF_o1{4=E2R}FyJUKR{i3A|NW2hz# zP7~hmD@8I75mhO{@p*^^DFY6rKMyt~q#$0{$x#(JPV4rxEm&)ixPWC-jR&C-uP(lm zaPS{r$#(|kcpu=6s-PI^ zHQGe&W;^g<68z5Tjczl^C+=8J7h<;6e6dh8W}ESvW_^&fDd*tJQqC$7WWa-^4Ty7i zkbuq0SrBR|GY~L@p>cMe6XPgl7OGJ!)z%%K_pQbRDV-7p?COjl{Mdz>Qa&*s)l0?a zKpCP%#&2tcGd4-YBD5y}95o|UZ#o-81i=><4d9y7h_m=oQci^wp*aH+Oppj=qfICe zx+etT1X0Fg#Hd z9O~$EQ-Cakrl1T0pu%z&VE$m9LG@-?mSOt>tmu`YtA=?F?8lHGtN;}#8apLu%&Q`Z zGec&Nw(3bb7eGLeO~7{$2RKPS)YEAY;b;+zfn-hiMIuQLFugve(ijWtox%4G+1neM zYYe#Olm!vbv8k`b4b>Ein+aEvq)Q(0h&N$LhBFQjkakV+f)q>a056jbdAw++ zJM5E6ZM~pnZpg)2g~l(X4}}8oF~FvK(cc9Yj?E_S3X`0M_@Z0KTrS~SZcAV-V9zqK z`rTwyI0TUpqB?-mo2#Yd9o$04CMLWcnClZmBkH-;?@zXmpS+j~mIc!j^~0c=g2xSq z{igY_m5?SRgvZITSv4wYCUekat8|g11OrZ5WrhI3PE!0b6aY}Uh@Z&Tu&4OGdZuXV z=t5u-0Npvy1#+9nNT|0kcV;*xkZs^gu?9eg86FcwrB~-HI?|wmFfCIVJtW+d6B6oB z?&|V&j;@E;3?V?QO#5VB;ETi;LDvrb>U_?aE7`4?i%1|KE=ji?K9O)xK5YqRf_3H# z@CiFmE{(N79Bc&VqtRsxD2+u4Lx)dL^O5)~2d9%yy^!|#V{M7K5xnd$7>D_Cww2sb zgfv4imE6vlnriRtNtToA+o|JnT?^B!eClzb=kA$32Gl{|Ya6B~U90wC+6i@J?GPDc zX+YM`IIv?vdE!yvJOX`TcZ@_gv&zLIl{hz@uMb*xUon;7f`$dh6S$Q*eA^DwJ!jvf ztB>!+T03|#Qj(Y~VX$*r#SkPz;HIGj#^^+#P#MT22F3yq;?^w!1rX>2DKMpZ?@dme zZzxE(l|&zlM>O6}W5^+H@|1I8DWYrW3+@VG+sHvws|#)<<^6#dtB4^l@hqDSUS)}u zf{zd32vogLqQ;KrFuj!vm6RQw)gxbm#3(ghe|7+t|hxdGSh(G!3~NmKUYo{X8Mp(~VMC~#N3 z_*gfn1d2Y)4rKkFIXy46)648_5y+Dp%aZk`prylAqT(Dp{W!)Pq}pJ~U=a6on%22o z9K(W8Y%QPDsL&b?IfP$JG$!%Ag~XslH86tqrIUMu=7*;Nrw3^_KVkM!)=#Ik(OTM;T znJ+aJdsec{`i>-P({Jell@hQrEre#yH}i*bXzlH_-BLAl=d|HxJ&NXMIEx5lU05 z2%4=r?7tdAXd%Nvv>`|~p*rRA0y$9FL~7R!$!LD#;X5GBSCeXjKVQbvsa=m#EQ8Re zB6A08Tjz23N)qSthyvPF92k$ae|5+JEl%CaPKkHume>LlKpp^$V$;z002r&EY3b1Z zPJFcM=A@N*ku;l_YCG^UxxIpT)Bun~)p4(bB&rR@0aUG_5kg0YCW0_aAAP_n;8e!< zfTjH&^-yp4J&i7I(=ijc8zo}~GpRG2N)j*O>>PwK6fWnSYR5g0(%-%$TsxNtceW6G zAA$f<7z2pU8FncdBeTBT+4ZNjdFWM!zSPIf9%|>RU#XG(`uT3KS*VoAvxeg{^?z>% zdo+9dXx=&s9t*sg)nCsw;F)S%kD@1hJXQ=eBEo>-_i)Ta1KO=W2Io*ITTls+xB=Db zjA9-BM4XrC5vrm(U0o(3tL(wmHAFg}ILnbKfxM33NIeAN0^ozHCJiI>gM{?Zcx!Ne zeTndUR=%%)zn1NAz7b?TtgQX$qBfVvrw9Mq4*v1`o!s+6ZtKTiO20nNdA~gQrMmI! zze^qJU9o@zFBV4<@vz#ADWiO_e~^Vo^d7N;?%uoW8tQBZ&A=wsmU(QssZG5t&P7vK zjWcu6+5rQHK!!LGViU|-*a~3eO<1h-@-S0QPZeSw&)HcxTIvt;d+*&nCYNfHZBjD3 zhU2ToPjCc@vH%qjWIP-}A9ixqk_|C+mx$8oIo>@XX|fJ{U0D8I2xUZ48|jpoy})H? zbH|K5gAd?)c|Kqwy^vPh93UYYtzi94w09k{ks%)Qdm3g9+E>)6Eo#Q4A-ae>JKQXpl4o`aYTwjI1_jC-T8@sLH}*hUGh?u4N? z)f`?1h*-Xkk86Bm;2PKkwjkPSD{A2Ekgzm}qQu)y=#E5JpuA)-@tMro zy$qYg;g|iN;0u&hyKUeIJ@-sZy&rOjH}64bixa9v$!8p0eL9(ySMn8H5GfW*Ik5z+ zmY28stn~PhwSPju$V>a5fq*U+NejyI{WIrg826`1WV=K<6O|| zNJ2r1;pmNT4l8gSSQqQ-usK>0+!M|rVy23PYmfq^8A0X~vFT~d_}7l}!C@D-o)I8` za*ZqPZ+i$WBS#SOUG5x12kszC!jh2S84yP;y(P%k7w;JC3dvBJKLE8z~eiH z_;-X28OpQiD7q1-p3N_dg?zD+FMf9T)xY|y|L*@d{a^p@|Mch)|2zEZpZ|-0`{=J8 zJ$m%)>fIas6aOhc`qz)3kV+rFTs^-DcH09BeaZl{UBr8;B?q3u67IAS)yiLAbl)8R z%SZq0KmOByK!9=7#nqub8^U#%f9;yTsbtiM(eN|mFtQ@!Fru@7A|C2S^!|ib55O5B z75W!&aRF0?P6cRPgUffCPLgtO|J(odKeYzf1OJ=7xBB9HgJ&4Gi%!JUe|HdCB&5xF9>| z1Ur|5pcoWt+l2!D@=9=NBWNJn3Lt^fI?&Ka&K(3l+Vw^uYSlNl!d9gaMa3|x)`|$^ zmWxpnsab{6W>{*ptK~IA%^>)7BmQx%)8eWs%`N<|QO>pNg?6rjd&#-2W_>GHE7t0z zO1ZJwE*00jw|Itp&*6#xo$Zicr}wA}u*ugf1)7h=sA82Y^nQVjxt3&W@mWG5SE%6c zak0K#u5TBs`OV^Hyq1oVC7jhFk0T%cZ5z^Pk!R^Rm*KV1^hw-Z_f{{{Zol2D z?tmg#GLEGT7nw78(Jr|uJG$k&kax@vUg}-d&KF!O&lwk(;jiv4_=XTJE?BP6SHaQfAvC7@QZI+Nw4YElPBw7TUVm5LkTf3)ounL;L?Nf*$dNb}43D-V8 zV|E~4V6h2$Ezat+mJ@~UEjh8hD01TpsUN10E-C?*=Ex%CU~aK6jw(#If{Y}@F0@F0 zgEZT2!B6eg;dQU666C}eArFC&ks!ieV!v%dPVn7rX8}}*ssAAy17Z9OLJ}yzZT#u$%Knr=y>NZOpVHP z@pxdQnVgcX6h)Cyv1$=-UGnPfvGHS(ZEO)QfWWupT1#_;1dew}D7HK~-q^$c5Tq88 zQ^V%l6WknXht22&DR5({^7dc}1@#zQ%QfC5kR*pi=;bdE=U0Hb_lAN~Cz=t6SxZ`c z-H3*3E^>4qk=$GIqua2$kA<2E{w%GOe25Kud%2Y?_%3;MGRt3pWwd~#P4=76-3bbZ zbQ_Qi3$a$|(h)~?v~I~Q?C7Zrc%boN7bLqY&)i=$oAL0=!EpinTw1lW7lpaqXW(#g z=H#z%rIEh{z&e%cVzQqqubt2Bo^k*@i}w?`K|M#2-389|W0A|p^o@9o#Y36}fRzxz z;zWygmUff)3w09qA&}brIZFNl1>DjUmtfzA=)xXOeSjC~F7e+0l=gnyiaNbL-oJ>N zN}#`HKAmFCuJI-oY}hzSJm;s7J8^0W=#BDbsnIOAbI}&E&?}8nE4S5ZN4YSnZEhmF zy}VT}PZ0oXT6>JCkJA&9(|Ou%QvMq+FG0jxXHxh{>^m;W1Xn4~cyClMh}*puTsRqa z8mO3tn|azt;wE|KC3Mcssh9$JZtqqbUr28Fo3(r7di7Zgm7pX7YQgm{q_rUm7_kBt z?;%R1jf)0K7E3)7G}1uz1XQlV9bw#cwhyNqEjPhG9xQH5Ze0Z&7G)uGL7@ZTauz+> zEa#MlhBmKee_^?%wsN0P z^!U{s0aSTvf?a>v@LV|E$VbaBrErGU|In)~NXmK`_%X%1al^t=_k>tbyA>3xB^Cfj>+2)p451dh)g+u)51KuO&#LoHe+6X(_jl;a9M>8kkHg3 zeqjGJpLIes&*N=YD-aVnb)6-CY~K%Lmvb#1e`Bfh^N4W%AoqA~bMN{rvLhV?S8Mgo zBJPRaz@P7Nb93)gEV8-zgWThe=HDe)WJ?Q-a_4(m%&9YTHz>WuiVBXb=3TbAdtnww zWEajTp1C(S6!yo#P-zYVdyX&n9yfT4#65qDUv&Eo)X<1GBL(!rcc`~6{a#SbguDIN zoMSOJt-r5HHqQ}oawsM802uvk{fsj=27WN$w#@5jwRTZ}4_y#Gwhe8Yyme0X+|6=C zR83};MzX7ixar$xlF!|>4EeyfeVYL7+zoTEK%%`5@q}foi$!{G*l8bSG0^~-JLOmp zaia?-2HmhtWl}cML)_%z_crG4(hcK_e8o=gmQkV+3Va4}Y^xu*}aUzH!HHnBU5_7ca|o@xK+KJZcJn@Q|PR(BP zzAsH7*0tD4Jo7TwntGvUelIyt=nH{tD%8Or%uaQaY$^QT?94Cs#MNjxr;x>n6C>hMVPbZL8dFhONeCsnDvl%A1>o zTC-JZhMSv>Qa!9Ut6O2ER0$j9cBxuylp2N2u(`RlS&bT{c4f&8yF$5_QSMzO*XW|# z6Kh=G-@aRw%|^RbD-@z~SjW*urL97%-6)g`wWuC8qRmEBEH*Z)jdHCKZqicmGa1==8p$_iQhWysi7)d%afJYKI|GOxyL%TCveCZf%8ya=8S| zu2nZTTctL@Q!5u*wN@i6*K3Vh)F_v$wNeHjbdpNn2nw@wPL;0-YPaLjd}$nj*MF%LvzVJ zTk=YdjfYT^bO3ZO=B$Ot{cXP0Y=q%vrP6NJHcKt=t8%GOEQG~MsT79ouoe}X?Ru?V zthLIOMiES)y#)?eZWjx+MpP+Pm)v}k0Q*sP-KfA#a7faP<)M&JCv*9!&`v?rYQQ2x^ zd-X=URt~|DLkM9AbNdj)k&}vq;>R`{+;#RW|w%aXm?ae0CliFsx)hbpRt*BfoRiMx; zf4cX~svBGN7I3x{m76V;;Sa-7u~I8F8g=L%VY6NR-^MplLwbZm~B3w!OKzS%vg1Mq#u*}-oy{s`DPtTT6h~gwjHAf=x{_G%kB1F*>bH|3=5@Zc?+s^J!(Xy zHa6X=m1`v&cD)5Fqf{$LP%FcFy;{Ii5frUbsaYu&TeVxN9`M{+(U#o9P(8}EaQUHiw##V#*=*IeqS{ue1kDP6Xin8yg)+_@dS$B`HH%TTQm7QGZJ_RdF_cydjNe0oMjH9nb z&2&>G*Takc(_+2|si2E;&wGv1QjA}e@Zlv&&GAj^Dd%Z-Yp$!7^+xl*;+Vr|#21|< znzwdR0#-LSQ8PU$KXEs)IZEzb=Vy{?>NfUTKfOgtzqP&h>7f#lsQrDpm~XT@Y;Y6} zASltNthg0C!z}Ep2)UO!@(BsKW?99AV!f~xJVvWJG^^W$BMwrwUVGy0U)JMxVRKG? ztsQN-DCciV`}bq;&iL9F^b4)WwUWGHN(Q6mgDIG?{}_56!=hwb_aLpQ!USs45R1^jjgT+4@<8Bkr zTd%*VZ_H(SpZ&_#kN@ABfAc^8=RZGs#Q(JQBYRm+wzYh`Nb5)K&+{~H^*DRD+AW4l z^|)MQ@aIbpu4s62*}05Z9AI*?Y5hK5uWT|CY1wX>5O#4FVIt$9El)boL#*-Qh30AG zV>%*Uu32JM-wS&>ss%Bo#nYO!2^U;vwT1LZBqEF_-E8^DFTVsQI#qtuL2B3t#HNyPh=MT*n5jBXhGq;N}P5fE@(rw*!NQc5?-#@>}niw}W-)0nt-JH@G@S zqCPtn3+qK|@($V}kp)_R;Nx>-Q{pcl;ZXV(n$8Zuz?khn=wBr7qlxeJCE8MTyVp#! z1t(*0oQ;Ij(_Eo9t~3efOl%9x;fMY4poxa)SZxqkPhwq_euJC?7EN$#>;^G>BF2!F6s-ffF9+FGJRtVY6r~h|)^X zjd$5F`30stAESA3j`{dT~bxCjU694#HNjTgm8B3V#{!@7I67cv!Lb_8Vy9 z2f~)=s$=np1q(1AIVP3?OgcLcpwo^?io=-CwLoOBQwr@W|AA&{to9-ER-rXM4FfFxjBL)y-Lvr5K^E&2F&`Xu_WX^d}4Ua z)u_m70lok?C6NLdFE$6L^#x83kPJvd4UpWa443b;P6Kx;0v?VOvvdT++SNj#EsJ%4 znB2a}VZQhQTYuB*;MAAdw;?&Yl;f}!u|+Ii^~YVvzX*SU#+}y8?dc)8?U4Y|=ewE> z?jisNok8f!=LDG(#DVEk%J@`foIyr|g!_~=dUAT+CQ?wM>k^hd2@2Ha4lo#9^@Ha| z$RI?VKTJi856&{df6!arm=KY}gb`5238M%_0h01@Na-LaLMgTL4hSwYMNHM`2v72) zwv+`w7*z_fh&^`!`D2WmV!kPmI|;?v!R)WXYcQh`|DQ}z;KKTF!*hpDdK9L-DN!P# z(#n&^I{q3%BxbD0lO;OZ1i;Gp5fLyrxSJ1)(2f@bf5bTi`xKDcVW;3~ZlpT^?bpcu zWX-cQK9du8Or%C9PHxaFedb84+3k->bf!k^+OM>ftlcCIJ>r(g`>IMDOTtDX#< zNop?g;PVhlXVC~B;b2u9;(dKilpXon?P`4;YBXO<=@o8^062s((GmKbvK}A^KzG(B z8=|R*B|!qx*93JEOtpKR55DYQ0b>RpaA3*XJU6cR0z6&x8LXHI#N-32^AUyvC}Or) z1x`c_M=?yE^f#Q~4$;PT!4F|?j#1mgG%Ew9Dx$)WRo99q5a1+>rUpyfiE>cpya7}W zJcPPY5LO5+>zzY9XC{lvrC2fbK&GxKKIaA2lsU5Wnqo8|fOK33py}(O398D;?G-=V z%ZIi%GJK(n22mH?zTTT3wxcPP3TIw8mW9@n&CA{?X}ym5ui4U#l+gBINUH0 z(=bQ-QoefE8T5O!emtp{*abV^9PySgHwfKpBlx1u{x3;!K;y9-7)DN*Rta&MD*MeJa6yk0|6!!AA%-A}?3#sGewZeYyjyCgJ z1}BB7&MPK{ihT$ZapB2|9iN7X$Fk{y%dC4m%)uuy$`uoZNHqmH38xf!AI(yX)_2`Q z&ILiuUf4XX00eErl$i9KEs%aJROyre(6*CIWU1zO6ge7O?}@~R55c58?GB7FP~A+G zq6T~nQay~y4-`c8mBN)njfB2SLEUA!@gx^siE(Derzvaz2CT&tYRSFiJRGs-d6?FB zgktMEVBdoQB{uvb9Y*hBr;%Qa=Gi2Rr2DopMv@OCJSYk_fxX3NhVTZ)Z*$==J$nwFLw;_E|F74}^{rBK zbF)WHVV(~2*DC|Ve1OdhG{&% zL$D;1bCP__`)GF{$PHJ+1-5P6Fa6;x{`XuBL(>MSloAzt(G|E}3l1`R5Lxv;I=c>j zM~3r<-0wItP!T_I8It?*2hNLcx7Cr2-zJdA0!zyC(q2IuE`4B4arM||Ix;B|-j~tI z|IgmL^|qC5YhrcM-RRT%B|y+`d07!Uki8>P6m_wrvrpr&EV)Y9w&b$ps=aG_w?vUk z5^ajq;l;A5x`6Wo8VC}gAMz*qC9nMyAV6O87jk|;fc%1d-xy=gHP?j{MUgJsC2!ZZ zM6NY2V~#oQm$Y3lW&YctL0lmrloZR98}g?{TYgG7?S*o;;Dl@wlPqPU^!^=(!j?<``z9enkfoy%^#X zNLaEt;vj0n?*Sx+IjHvzmOQoME+a_m9VjRb>k0cMyH8wwVvPu1rO$aO(ia0EUi}F` zNb+ai5x17q#JD$|z6NU;<1g5aiW^W*pvOrp>$r0Su4L}nBK z*#U|}^U_d0g*d^BO~FF?3-A@shQwe8?e?q%4-w1)^ctDZ#P$fDCGwf@y>KeG@eJU? zt*0HbVyg3_nkELnue3w}__)eOyG5N$)~F$9sJR?Nw8fX^gvmXjU`h4_j}vy}A$l)? z={)Y18*r!{^PXnzmU__1HkC@HiPL0Gi>Da7m`uF@ih-=Fxa97WEC*jeGz2wdTZuWW z>FBy!Y9ok)W+%)5b5G!t=lRL(FeMQtInuCS8%G!jt>Vqh3BdbUqgSKc+VhJ>ZLf={ z1`ieRQP!VcBt-At%`swx=LPepv?0J>y?1yZK+mo4se-j=S#yG%TTK;`BzxVSlIP`$-WKw}P$OC`L0c7##XrYaQ-rG^>$!d9HWo>h{ zvV@P&aeO;kTQ9FykW9K6{i3362)8`EW+uHZzJ>-{f;fRIB80ioYe|B<@+AizXzJ>= z7h@Q|I|su+%n39M32R{x0!X;0U$cBs94dp_hRAk9#j|QlRiPcq=qU-0o{I zJurLWm|``=XD|}mk9oLlA+@UF@5otw*dCw?9@elO}GD_fvAFW;r<4x$~ z5i=K16t9v3tDqwz;J1w0G)B?8&54=|L%iP+EYf;nb1K>MVmoa$a87s2(FtHvwuesW zo~w(Ci_wr~kRksOCzXVYh<_l7-b*OP4-`$|8|&RrAFy~4A7Tb&8vew7R4SS6lMWn6 zQCtWwe;=lxivg%Y;*kheFYg7k2XYx56;R4Gpa83GzNH@xBaxu>;a-RHW;1t?z43w*f+LC&%A+qZP&`k%*>v$CHu7p_B9K3G_tB@|74|E)g5F!`1 z!>~D?hANhM2o^`zIj@D-Rl|c%;s>qG9@Py-9lH4>SVkc#vo>Rf$wdfmyFy4AEdpi4 zsPW`t+-eCHXMP1@vnYrG5CEE(Rk3fB5tQGFqV;A|zJ%=Klv%}4Tb*d3QXE##{9c-* zS_5#O_-B^h0nm8(9gu&3dtYW zMtB0gwkW9>mm8W6z>XL+wQ`UJxJ5@7s1wITsGC3@H#~RGoFrPh4!UsKI){IQX0QGN zNmno;oZT9jY5-iK`3Ha{Wx`d-483h9coN;H#h7urdLb|=^)pgj33ULU16=?rzK06I zg9TWGHxNETg}~>6NF&Nid!i?LuVg{_xc8FxY!~Tp*5a zgoC3y2*84z!fio3caWw9^qycB7GGApp& zxq1rnDkGYJm+nOPYyGs<7CQ?YA;nkG@Jgf3WIn+PyCiAoNpz~LFbyxVJT+!x|4ZS? zB~h=0P#&X4ik?O3ToF^9m})@trXWqcl@GxWkuZa>M!n$( z@yGQh&Ck7_Khrwo{EIkrFFF~7-uyJJni+5SmJte%!0Vv32%tes@Ck(9^SB2iR%h^- zhtsQH8#~5j#SNECDg4+(uq+&`^!2LNCHf^+sH&0C^$gUFfyCea_fgsK9-N%Dz1)|33jEFiY)<(0~c z5!;+KD{o+>PI(KyOk=%-{stt#->DUd3s{hV&C_WRswp!q1A+J$2(CZXLujB9LBY}t zuNi#p=zOR(CP--l3QnJ7mAQ##?g%W2e45YUW{4E&-_EEcq7m8?0FJ5=DmR@E!GaKx z6@#D)S}RL%)(!nAb4Z)lEh9YWo{)_oXb!=Mppg~WBndy)J~_B?M;9@~Wym>5 zzJv>B5L~-n%ss;PfUHX&Y;3%c0Dxl~0{b9wCrCJ;g!_YhLm|YC2XHiDk$e(hlM4mf zf|H=N@|-Rs$c)h404~Zo;Cgw~7f1=_I`XH?ZXU=SN)*OYMM04b;2doaSr&e#BAdx? zA{kPuhPC{PeV0@$2h><^nygHR#^FG;YY!38BMOWOhz=?6Ts_i+BNJa#AgKwDCadd1 z3^|e0E$fIUE{woXSqL6&^PE&RqR$loSq4o(85e*8%RIn*Z<;~zW?GVA`vR zCG;ZUq;O8s`iIAq8)IP|2I2>?C?v2>SfBw$1O1r;u9q94DMLVY*}Tv$ek8cO2}v@X zaex4~Ll%H)zF?$SB0RFeh5}ktBX1_SbiGbaKyVIsEqDA1u>h{6=Ochk_o6G4O&V@O z28Tni#XT73w7rOI?P+F0wcM71EE~1E$*AxNBjH9Ptn|Ji-4?H4Pt;rz7*=M0CC>*&o(s#G$Tii0LwrHLeE zZN^D+fm(pT-G1`5Z889eT*ObrTia87UsVyRI(nmh(l3ZNa;qKmVb$*!q!k+YQltUU znP>9A;-SWD3DGhX50G$IPDpNtQdj4cJiO^+GlT%IS=uJ^9A6~12%2_iSLbs^T#3IX z2P2)6xFiJ|_(VcM`LvZP5Uev>KzOkurP5dn*uheCF&JDmfznu%+z{9VHM8B32^#s- z3TdA|(n@4Y(Tf(7w=rMIwo*Do?-d4Flxjmts-5%4c}lKtr;f`Nib|96Lj4UfDJ}w8 zC8%virD7&~H*JJEv*3<0bN#AJJ$#l_7_?$y3gVrHBr=gFeGtfd~6ErK{EjGm_GNbSU<| z3J-blXW48_Hlx)DbexF>lyl5$Eaz_0EMYDQ)H-Vh8|P39fJ%S3&+U zh?QxXhOgyBW+=PY#P97DK+mo9Ry$y4d7I*kyY+fmp)bbQpyW$1-5x#$NHm;NW^+%v zN(l~KA^bvsL->qa%@Tz`k%w7ZrrW`Ibd_IerJvE;B9OBi%U|m!sT)m#e+!=eI?5cl zT5n2c5ciaF1VNmDO($?dEr58I)GM?g0toE@uxp9!4VhxF+KAz=OU?0o_XKuBlOvvGAZQtk_#yu5(Gqd!o0dj1(A7{P2YhC`s`Cs} z;7nm*Fc^-Sz~Ppwe5ORR>Jb)Vei~Q12`a`Y349xs6+FQL!czGk-#TA5WqB;KuNMd4)DxS z(lJ4lVJ+PBMazlU(_FHHtQr;0=jed<1Zg2&S%yQ9Q&jB8QP!DZ=JQr(_#xsP(QpXz zFD2X5e6&ov-!dfLWmVmlVTr}fUgpE7H&$lwI_)h;g3?b+Z4yk7msRM5p#X*-nh)R{ zs>iRd#}=ZJzg)Zt;BJuj?O{&X{)+|URW!ePgqKje=?|*_h`(OXs4aa!XBu% zB{xrQYe2dKA@CW9wV@jBY{y$7#N>l;`6LU1gV5(SinL>({dn;8-oYURQ?e)}_EPRl zQ7S*CJ!r-gH-j({XSd0#7f%oNj}8tGCIvl5&C~IjT;#=XZEU9|bFKimFwOWVJHs>D zZXur%=TF?qPDrFtRI>?@6)~1tS;Vhp14PA%3q@k+qQ8hIWQ-veqxLSlnK}{W3TUt}rJP%} z))-L_hzM4zH3dF-P&Kr^*5Y%a9Tzt!8tLp;pVyau`FE*9ofiq%4+Q!A^`~XlZoXdp;L-<|9rx~o zt0JnNdu_)3k5t^D8Y06jA*pINS4*#j3)=zX*kE74i4dD$BWFD`o-mN#xPhK3m?56a z*c7|{^6n?8;OfH4$m?oBo6p?L*=S=mvm86DhfnDO#rn*3bY|X^I)xzw-?iZ|X`LY) zq=#e_9*}BCdF%KA4Rpc)jm65%qH7(Afe^~UZ>hG{Bju0aoGv5~mP*Md2NzA8FF6V2 z^(h3Np+V$U83b_DP9JFy&P;B^@^$>^k@IpORtDS-Zu$5WXNPF79vWKoQK}0StYN)k zU09{xUfR_sC#SC-W2q`7vB}5nV z+`v`Pq~?W$VLp>PyBGCF1SELTeGA88_6P%Ck7w7jL%pmmo9rstX8T3qqt&ewoqT$!pOTolm*V7w+>NqV_WZ)ON@^D0L# z+b~t(c?j3TzGR*=0RaG!Iy4aJS_rvBa}I>wG22JHzR*{Zmk#X+Vzf(l%j>SP9Xs2R z1lkdQ91*;*bpOr?8*(?#rqeY0G4v8`vsTv1D=EaiLKCP?AH89^b6V|@MQ@TIU>0&A zDY@X3Z_;QflttSPA4)zDi;s(0==9GZcto!QJqB+KFZr5TAeROEma!e8H{9dYwgi{Ul|ks?4v7Uve3LL-1r2G#N<+7=8i z;lIYsdVk5=!nZ;@kT;kyct12Ax$3K7#Of^;fV53x$UY~NP`)6pAw`!FbAq^N4XF|v z1~LI)VWivjDtCY@tJQVylI$Ys4^df&Zt1ejsF~gm(w~kp!9UY%JyFATJ!aK(6*rys zM2(j*Ae7;@z#+u%RQ=p*KGRu~~_b7hvWAH{+zY!971) zsVapE`+-{Srkiwmo^IF+vlbt?HczM$D=p5R8X@i*Ebe4skSf@4NyT}uA-#jAqolNK z(hWI0EPHdXx;c>B%v@zeyNTj4NtemG}?rKUs7Qr z7S*G`f%CEp4N(Y>L?l>C0%t~%GT{_MprtW34h^+15LRc%h_|Chxc6PeGqb|0t#O|W z1K>^I%?AN&E25u-r`^hz-F9cJ6{Nr&;;);}V*G(8*p{Ob#14-eaDNR-S6yUgHyc)U zc#NXy~Dgg!;;_dJ^#O4oqjA5{VMDF_du@6e0yLvSOFipGD0Trp>-< zQ*L#e))+|m72~UR_l5|y6dke@0c;M3F@D*pGieJy=8YBpt27<-~~ueuH}T z#$b)rf*!XChbjoYe+O2DM~y|k^dF4kjz?guOmmXv8152>GJ;lupj6G;qf#BwN3Pm@ z8s(}t&}Qh;LJP+Hl_W(hj|#YT4l#|7 zGYZnGSx6yCFz71cl@TMr13{f84I>}m_rR$IwoMwvb|Itj9g>486B73V`?^p8Qq=q-Hf_lS#gb9Kr(@QLC36EP>ihveag*tws zV5wj0SK=G8y2&kyv>pr;Gc7&Kt<;m{MaChi9y}p7WY!NVHyAo^h4X{Y#x1s3OX@a- z#5t)h)<9+`E7vihT^AA<=Z?%^1LGb;07y|0DUTGw^Qh6gxf*m)TI~w82eeiJlw{h| zND{(PVJd7PfkeD*02LhfHc#|CX8zK!;|+IOdQ)82nOB^i8myKDMo{|sB1Sk_LB)vO zSFa9U9lzc`diDD7Xm{uM)xp7$Kl{5Q8KS`%7hF`_cs56Ms1taRSHMV>M>I9pI>lq1 z&)12bc6-Q760zqV`;(K&CHd#KHs%&B9x`iRjW^*zJ2fFh3KX7VgtRR)1m)b*w7g0V zBO-Jd--^%-h@F5d8@z#8nAl82T&Cz*2i1gDqb_E;RZnB&Ya%#5r~wyXq6C`AJGq%% zRITIhJFtwzZFKDtN=(Fe-+YT2CI|`YU4cY9Mup*S&p*&Qf#uU-|2VJN&PY7@8m<@) z?&yKenW$*{@2Tj$?w>A6&&sdah@kns#t$!*%jF0i5vSQy6IEdID%*@UwS$8d#m0!0 z0W#v}R(w&u27;L$qbiahBnzN`rAh&L28U@+;iucMS!{F1ccJGtF>2k_M}>RE z$78o@8{3ZF>_|DvH{as=Ac*GO_uV!MW>y`ky$hz|wz1{M97SmkpIFEZyjJNEvoj}I zl1NEZktE#2oloI_c8KtWf$p+7*mK~HJy!47tsEmA)-p0=C1ssFlo_J^l>hCc?omND zuk-s}4&*+^H_hdHFZg_{aGW0@UDSKyE*)uVz{j6SK`zSZ%%L;!1=e&;GnK-2h~h#K z<_=3K_vu{Ib%*029BBs^R0wf&C`nk+)1A_*gBRgPce}Xl_9q&jNDaNIt1Dlkntj|n zHb=>=chAMr9*^>9LYR<#GT!xqBvKrUNUB!!1+0Mv?WBRZedvs#X%*n)-W z5|K1u^@a%^pcbRcBux2k355i50e8yAd{0BrQYjSe)+wsMhBaVClTGSgU>lG{)b|x~ zZwWJiF`CRNAN!#(X{%Kt%bi#=wvCYId6l$#hS*9?iQy#fqI(!*ypK<}-&lo*H+rvE zt8b>=Sd7N7qCg#+{VqSCG{%5A-E-OIt{+~dEt*{@WcYQA++@+&UZ2L7Z+>{O_Y`(A zx8CWtU2t>r_JL{6)oCws6DQy8Og05?!>xxninhCTqXe&w;n8iax;AlY8QBj6$^oxZ zHd1UxTFRbU?9DinOr~i!p4#IJ@%%*4!t7Zst8s&Bx*r%+=C-{10nXMQGZl8VNHNtL zglWKD^|FtLxS6cQDVg9Sj!jtH z5%v<8NsgYsSc?7__mD5m$Xaj*i4?58ybFG~{c0D%iRImC_W4xW5CXOLUcO)Ba`Eqm zmxqBPaI{F-CrFj>y1YlZJMz{$-FCN~38?w4BKx7D!X5o)ZUs0lk{Re^xAK)~faw+| z(}+0@Ud$W~-edNW+P0UN)XSh5rLa)^*%4$a;Chm3d(6dp-ieetR^mvrP(D`EYAacU zcy61-Jfd(I$-Up&UGIxyje;3}tw%G0306;vhDw zKi}OEr;UE`!`{C9aHqo^bl)K(RjLF{Bsz`pt^5#FkdraQZ@YDgNQ~yfeRexH^7rX% zmZgNxS;9|`c79g(Z-X64s<(6Dn-(+vLLQ;(-&4}1;LKJj%6FO6eU^zJlzCh#=Voq9hLI3E8 z1me(^T1#G(4B#B-jt*d(j_^c(oJdKq*I}^kBjc?(NpkiCBy`kbZ5G&wcyRYxe7%?DcJT+e zvtdIuszm~{jh-bpWViO&WS)^lk8!5Y!Hj+mFBQt*LI!tz>wKh3{j?9GKZ0k(_GTtU zSX#_L6xiio0FM#005wlD!|^O;prQ=iMkz!c>D(jiKBg%(?cOi*v5&8`#=Vu5*3KlBcAXAmJtTU2fJzX6DH zCW-&OjPzwZk-We{MSweKsEb>KoI-*!?4w6-3;mij3IwD)5AwB1xnL%yt1u=lYv&$w zmx?1j<`R*XSvkXva2h$sTp_AVb-|7x7Y8<6Acp9sL*wZ8@Y^$JD31z=HY#(jxcuR&L4(}~ z7j%0ot<8eCAmDFy;C%@BnA|o~Kaj|#5`}R*iZob&8eLp3!FBJ3&FZ39S{}4S1Q;d^WGB{fhIeBOB z7IRcuWj@2$NhY-;?(Y~`?in*%JBPBs9xeuI#UWq<@U^n1@&=K!Ay(d z0XLYi?gXuE2<{chkirEH*`!rk+vujEyvdJm5#QBj%4*MEo(#kiDQM}xaDJV82>79N zAC=macY2W*>L;a6(1YyJaZ>)Mer=SG5`(2Fo1$9f^yPv+VQb~h_0`GygpG(7C`96E z`0V27kO8N@ggOi4QrC|_;_21E0KpS~bA{TZO_MepSduo1+D*c_L!n_vp-5kPL4;Qc z{$X5}j~CX0MM%GBMz3G*?I3qmnt6Cn>o@pNy*y~^%~pj}UD%^`D0LeV!sVo4;xt3z zVcWBYVSbVTX`dp@8Vn1*W=4obnlgt`bT~H{gDbFUX|jXlSzI4_6X@tfdkm!+aNK}nm5MDQ^HQfD+*eJ&={np6Acjm!7EoKljr5Hv*H{mH`H~@_v zt#k~G7HxHc+c6cgeMy#s2~wGIaDA{a%+tb<1~&?5(sFw&>AtfrZMWl((wEG?}!e!(q6{^sovT<=t+s1M5 zed?$WFVH~HLi{Dw53b2^Agq^T<`v=prUK4`6dP92dyrxUiJW4PA|Ciflh4z)=Rr>F zJjjU!mfGoJeX|$`p%FDF>Sb#x=Bp|>2WQq0=pRVY)S&8;ky0HmdK893`O-9ZW2(Aj zS!LekKD*mNolvII{5>C{OTpTOe83$o0ya~5hX@|EaL{f1&>FDwnU%+8e?mB~5cksW zqdXmpVIctywSVvrJ1p`i`h)6dkcJ3Lc-P`YMcaqJj5X$=ny7OLKS+u%8Xd7VlvC;~ z48;lk6X&U=aKD+Md|s4vNG}r;*C<$Okj35GQ>E}sx006)XSSIcN$`w3v7o{UF2p!fw+m|^ z2pzKECgZwyByOBm2JzSW3DIjB_JzQV@zRAs_(ieA1O`Ebag4e|%_OSWW&ll+xNJwA zQLx50Uqmb(cLvjh=I;5#5-f?`$E6_cKqruMXXq}B9sL0;i4w(zpD?X|&*o%Fv+Nf8 zFpqG30XTzwDTS*c+^mCYXUYB@nADq27kv?sEOM18;Q)p8oMx<-mbUBy1}v5nlYBB11P&7~@SqbhFzJSf^)LpEIF9Z{aq z8sX{p2Q65TFhT)<7#N&`HO**vJV6=4IYiD~wzcfa$=q@C|6yP&$ z4v37ZF_&J;1d<}&yO%#G2nkbhhViLrGb5@Gre&qT!C623ZJU-2@$wmE zSw$fTuwv{}9TiYD0m9>Zka6Vh6`Hfz*WQA4mn5^4#9=GVNXdBQLCKDhu=e1LiIKPU z5u7o_c=*{~An`X(AR6Dv^=eM++~uE%^EL5{xual!>*u?`_vW{AWmcw>MHF7*z=GXi^r7WRh$0|EKazMC6K|n@A{F>vQnvZ`C)R^R>Nj794M(JgK<4q(vhnT_rj_R;oSU{9Z1}W`bOXQB zw77aAW*7fuDBqq0a0_h38k0}63HNvkN$(6`!6tXVdoF`vHteW3L>M?S9S}xF6AH8Y zThcd|mJ@U&=(m`Lg;5x5BPEukhaikYr%1GAIVJY#6!SE#Q4E5Cg#@oOyA8=BK_NR> z!^4%U*nNWI@}H*Q<0bPG^a{-)i958^G1(D5jt*WWV+O+nGlh^V2ak-NN#4lV{U0Yr z`aQaYQJ^2tL}(Df88o1w!HA{3+pTx7+}?y2ofeH6#F_>M0_SO_e`X{t=xTpc;zF?H{Q3O0<%Q2! zE$X9Vv^Lstx<~&Dp(h0!%j4~*MpxiPnn2v_O0{u&Fr^IbB^jdDGlkMj#_eHlEb(u_ zHJ)}u!Ql?~kwofdoorUU!Owe3mUGB2%h*_%el#n8iAsuZr4<|fzT*PX1EoB*(Iae2 z#&BH%O`Jx5N)h0iT0IvfHM(eC$@poXloP$|0XUc` z+CJ|>O1Zd1Y4J8ogLf~HajPOdge+tm(Vs>W85~gBGP91DW{X+~BB&ugT1npp0Ozo> zAX4VS)u6vzStv_eX&J*etHC{GJFOn7VoPyp&hngXG?B^N>%{2tZX%>ar{_#U6DO;V zKR3c;0u&u}ZVPg70bspKq{Y}ZYtv3I7gZmg_}@h;kweOc8e-8i9ul4Z=b!#Jw)doX zu6Y`0V;bYUSmA{VPn|1t;=ax&ZG)iXF!B)U4t0!rWJ?i=Uc9{!Z4sr8Mly;={lC-W z4z~n6U;;8D_42`86jS69PZ@wEx(UE{5PQ-X`x&?#Ju$U8M@*M5;JIE#TZ+aV z!Uf(RzpwXPv7K>DZ!~{j-0i$?^|~EaoIsmp6at62p&vaui90&_$z#wbP&aMoAgNkL z8pWQ2`UiI{G?8e^gp>x>1+A4STcCeLq^*7;T{>cCY6#arW+sFE>}e9?6SE^0sKSds zFT6h7eYLP1EuhF3EKZGurG@9U{cq%x&hhKR^6R5#rA>VL?ZJy(eyXS7p8jR>Kt3OO zHUTG_iRJU-T#GSmf^yb9L;EUJu&$ICRu&ER}?lU6K=%7w^C%`%bIR{HjMNIh zsKP>H=!Cn^pWvOZ@RGMp zt$ko0GVq%`6G-7-P6mF8HYHghvqQNrO=F#zaD7)kt)f#lkZNX9+Gt`R6W=$jCWU9Z zl}}&f46-~XxDeywP#)51V5ASg8H9m6q}6;vX*H>9I@=5Sr7?nEHLWIfPM>B}c4~=1 zH0l?@!GitF_Lih1^ch)Bl33F$?5B0pq*j@i9L(4wz9D0r-mW&U+Aeu?dvHy`@V2e7 zq0WewiO0LARPzvB+wYejqH76^e^uJVbA=q;Me5T#>czx&7&BjUJ#m_6cHof+OAk-{If1dQDU}Jf_o!QoAq=kG* z(X}Z&dx)-;nqZ$pbnW!#)AnXZ^C$pt`%jI|94yW zg^v|o%i{Ot%jWt7=A>!DvtI11OMQI}1a`3!GHL&!?t=8k1tm^1>*2Sxl`+#+*Ei<0 zT}+I@$4tGx;u_e`Vb2)6VCukiH^HtSJfX|_!_GSfzP377LsT>9Mcv_mKRwzzc&s%reF1`^fGfa71O6pB3&j^=Brv!*jC`#D zUCR<$o3t7i*~$Y_Wb&FlEhQPs7J?6#7WRbqq-^fsNM}1peWD$NiKD|M+gJX1x zboDxp;}4BEPP%=LqfleW#2&f>pt3;v4gpBW@N*?FZ4Y1rusQ0Snhb_zy=%3*xur1^ z^Q?6~L=iC-)Ig>N>tnj?l1X+P7;VPwE7Q{{C1frJc#)ifVo1M^!d|VPG@Vh>Edt{3 zHR^yw@fkwdk#NV_7MG~$%oI8_C`C_2=FK5T5$DS$OZr5kex>aeks&gWiVqS1&-{>n ze|ULCF!%(K{evTBSn8;3(IoaO3~2*mQ)nV1NXXI|7*C6WSZ0e9AyxEdS5KFi;!`gz z3s!>vljKVV=A&70AOBpU{R|UpP<$GVL)k?~3-7T43VH`KHS|U*q)N$}s5z9)2jc_G zSQt83FyGYG`|v5IlB9@?K=how6Os?Q1LS5aE;)EkKo~}4K~N%-AzkJy$b$@y4A=0m zaQ7|oL501EurpX{|6L15HA%CnyRTGf346V=?22Evok%7~v zmUcA1fEdSgtPoc zor(EFvN)tvG%i|f9}U8sCKd%Nokll#X(hJ9iOO(5@;Y{qNGaFrtk=DieqCS}$$H#= zyr1sF=Em{H#QEvLF4LVLZ{4TnDB5Ewp13dllF&o6*C%5JN!)#UD4gP$ormiLqg8E+ z2X6hhUiFbHEf;ox&ZE#6@#O0+dLIDNOiWk0&Ezvmb8fjHPgkIQU}$c^9^i|VY$i^Z z9K8)>t__Bnl&Bfu*WyE`;%Pb+k2$N+O^fr0Hw{Jjm~D$kZxfi!)@QfUf-zU?q1i4Z zzC6P#r>SkZpzm(M-5&?%Vj4!d{xj^l8=xe#M6zCRl3USmnv1sAX`=WHv|dqxlF6(* zq=Y^S@$WWZ1OiijjS_W(i z8MjnP3ebkTE9WDr^VE5i!t@MEYESy$YTph(hsMARvCI2lSsqyAO> zS_&HBX=uhh2oQeMDRxB%(yeDU%{2g4qd-qVfv4WE(+N)Xu88)K<&EYV3ro>Lsm=fA z`SD-hX?o$Wca7m%n z?E#!0v)GJ3mWNu8gX7x>rG%t^wk03!sC5&w4T(rQcBiiV7_QLeu0JrRe(C(73FhEq zFsD??N!}}v)%63P07BY6PTSa`EApAOxwI{O)bxP~%C3dW`gjQjcVE~?OhLH&;yz-M z!sLs4NMpEhk>T3WkD>QX_*~g>1wX~To^P08zRYw8HZ0}v-1cF#r(Hb&XAr6UP|&Ri zKnxJe!J6&}z_TMRe!3oLVzN+a#BrZT2&>NfAMR3F!)V!Tg}hH8?$uc?f|z`UN^A6I z=EK|a#&M#UY?4p(RvT;a zR<*jqADWH&`qsv3z202iXg1I8e#_CZ4IO)tMI%>Xwwx%q*4wDRWfbl{lEG6H|fn ziGoG$q%JS+#E7J4$YoPx(_V~JG29#6{0{g8B0bQ|&?gTtjsx+77AvUnh7elOX%pE6 z%u8f2$cf3e<*b??wx`}pioILJo;*zgWUnVNpc22BG;j2`YGSx$!Imp%aVLFF=q?UVeo8VZC6pIw6%Jv zbY7)pO@~VMnm>_gcROB_%BV4_+erTFF(cECgYQ#}@bCh%k+Fwf1Q`Leavb35 z1N`3|k3Xzz_?ch0a4Y%qof-AG_l*l`6=oqmEfS`1Cr{qSVa}YdT(H^vnM}Lg&;8DQ zUL_fgcz#K(&c|#ikENduFAWv!|0amf7L^7!Iw*J7h0No74XBuycyv@0Vbh zBye3{#1Pw5c56_FrsAV3Kr3>YT8yzU{Gb#|53&-Hdb=$b zdW!6HMEP}D)5SMDN8}$=6+3;{%}#qz`&o!XOW~k1JBB2voGaowK1I)VSgkA-4M}(1 zD}*52p@xbP%P*<=YqF&>>&qN#FM8BNf+4~XbDZ%$xVtIIi^r_SjLz`#6vqPcqV4AN zpsj;_QPQ2QKvG(K$s5$Pc#js@AZ0o#eSE0Y3JlQk;mQM&uzha(95%Ya#U&D3+c;tv zJz))nsRRxwU=`x$HG5I4k!SVGR=ZUP)zl`vFvPfJvT%!4cv--CA66E`uefkE=r30m z%F#1SEn_rebggcqLK?yhne5q%Sq{eBU(Z{e;fLrQd=+s!YIYk#Rs|9ZY>pb-wQ5DK zQtv~>*H5$JtKG06N>p7=LbpdJ59Yljy}Tt4Wx&Se|VKcsFl^~T^%345#xt! zGtcyYqdM3_4O;rz<qzKgaGpUAE60(-O(rxw#9iL3f+~ zE*@>akRDX@?y!%Fk>{C8euXQVjvMrPD4h$5%V|KEOq6OU;F2&vbLKVle-X**r~Phw zh&sYob$+5DsflSbFiX9_sIVR&st2Y3Z!KWCDj1Xy0z1$GntF7Ib@EXW-u$@umxbkF zzqbr)!}9FP-h?oHD10;5!Z!}o34Y9uypK1sew^aE?w$sYb}Btn1sQ+LTuup9_`Ks_ zf-U6D4l^T;`%?$N$ojr?<4>~5{2Aof^@Pl6{Jk!`X`e*MOBf(Bk&kXdc%)RfeDno9 zHZ+yYB)BZxL;gfRfm;;>d}LufExz3X-(MrTCD>*D6sFzhXM3+;0EBetvb-N8;h9Oo zC_I~m?1MZ!PkA^4aQIPChOl|ejw}<%#hJD-egG}}N;J!H6q{{p`7`)aMB${Lm0tY6oQ ze1TSPo4BR)a0XW%id#Gsw~!k@&&o?#obv%|6HuoKrP(iyYJE(tJ###txBgzZnY^_7 zDd-$&F$wXVNPNAUi(DjvrfgG}OyEQgha; zyE#!EyDQ8Fo;YziL(puknNJ^X&BLwvm2OQ26F=iiB*vQww8tjOH+Uu&L~R_wxIsFh{`4#rOJA#x_VUE+^(!|udbCh*H?d>xFt>&@Dj68{>(RVtE1!-Ai;q* zH@n=KX@K+gou$>pU`MkRn4RJVpU8H!Kec~4gX)PVHw*t9$DYvAlUipU_P>f>t>B0r z5*L6%2%JlUhSeXB>-}R>Oedh=;|v|rm(Lz3?9L?3agpnVvXP-KOtXcnL&={9-79OO zXzL2}D<+Rw;27KkXCrF(WcC&PJt}k!;}g7rLP6-*n@$Ci7V9h|gdX$I%b~`@vciSf zQh~!viFDe#8swrK&0dSB+V_%m{Qd+^jdw9VXf;oe@-S?(4ZRE}d(1p8gE^-s-X$kg zSfH~M>yXj$e~N-*$qeZ;JQ1(QiGvix+1`zf7nU)Sv(Y+8+L6q~^qnG)^9*3YCU?Jk zE`w=#v)&Nqqqu{jAy`Epo*3ja4;GO|$ae2nUHBB4;*7{Z7DodIjpBbq??T$8PUFEf zGph#IT^OO_HZrfIJ{tx(r%B3^`N~mTK2Nsg1@RLcm)}ncKEWf8a!BG1Ep<$GgpZ?x zSIL;cFu_bAp5#M!O*<1QCJpDai#vIdv{G-m-BCjQcR<$)f80++^rJ{I%BrJv-@8+WNznw|&y zdLK7G^LkEWw)8p34MC{NZ%1$lHl07CY2~HyhR{zq?kyuZd|u^eve$3OzKxPmZiV9d zxyogqsX|gzVJDBhGuzzEG?Oo>GDHU3a`grtDnxv$6(Vjsxra&-pJt_q%(;E(0r^GS z%@g_GxQOylok2@8;Qv3B>I|QfiQOf26$wmP9cO0ZQrq__ZEs~py+?abE+-78{(S%$-MQKPe`-V|DV9O(=SVx(+?lCj89X`kb^>5gv-t(RT=`ml_rq%@mOs~cwLfc z+=dPvp+|)z#;AkD7g)S*H3t`oHUG#JUhKDiqGtj00z;v<3`>K8@W8k)?POS1u?>Qy zF0IS@ht}or(!QebQIF0M(4lA1yA@KzR(x zb~S`A$OT;ZN)DS7S7aq9S$1>+m*bt`$Z_d$q6^PKF9XYqxOILp__Tppow%;$uU8<^ zahoq);eH4oknn*oT%{f>S;W1{CAzityThJTPZViXfe+wdb#!2YufO*Wkr~Q@makZ!9jpZV zfbZLa02m~2)x8>`7mmwV30@_qK`CH)af#U$8it_38CLq8$ro-Vsfnclo3bej7D;b| zQxE%yPk^^OSps+j27Wv2D1VdUM*s$LJXD6)b;~ZmQwd0kkH|lQ#8PS4={lm4^PHlj zF;jl!mHve|{@H=;hIMC|oWtw@M#P|GJonC}pdK<}Q$|eXHZG|?3E;x5y9^&4Pzrzh zQJo-+7FuNH03TP`K#&RMmd3Af51j*}UKfE1qLnBI%|Bts>G!1N#XVTX_ph~a1jz)$ zQfaUj3!vj{iwNNG^*rvD8wesf&a36qnln@A{geSJg$nr#fS=)U`Q_jXoMUHztof!3 zU$x5KGg;Hobr*dE5f0J=4xpDnkDbnNy(HI&=O?o>@}|g;uwRoEkD*;D*t+571>k+G z(Ic0e%xSG&P~1mnqKl|@8TU|Zya3`u31e#YyYqtiQ>0`eQYzXzJP@GgR`^uGnueV& zYhI{nODa5N6!Nb(^N?zH^*S30jKWIXs$*$c;ZY?p*gWqd$ZIf^CKk;I#94mH0c7## zXaS=5!gf@8vRd9)S=(H#Ea9X203WTbm)9%nTPvH70C0l$c z!z&pp>QLa9oNV;_dK+PvQT+;md+5Q6%~?Jw6jFmyW^*BwgAdZRs$JRlSeqdV?7ShU<|Qd z6nnM(TJT)q;*B9K*Lvr|e(TF$593a^e_TV!a%Zb3G`%`{M@12*VbV6K6Mh>hYjf#* z!%4`FSm3G`S(4>Zsg{Df!4{|Q>yX`CaZWMS=)HQTQMa@SX)9s?1{-3jp_ zZGy}CHkc+=%}!|9Pb7(;83NTYx#76nb)+ds^PlcnAQL>pnfT-fT*l`+wU<1nnv|)C zc6?t2UB2oIX?ZNhzEs8Ws64ZM37X3UQN7s&!8C++SbK)bPX%hnedeE8H0@oCGu$V% zF>XgdEW%#>JpjwDZ|*jDU8mMY7pFnA8}?RpAQ8^+iT2|2Yr8M``v&zdu8Qd&N}^9g z|I$mF7ZsdyutsJRbEAnNwb40^ZQV)*_363N!fatu-|$$)$q)Zm0n@kD+h5Ko{QifNVqo~a#_kpZEM z4Yd){GE>`NoW+~2wV?w^7GGwfx#V%BK&tY5WU401ZvA;=nsx`j3d@~PuJf=8TA9E6 z;L|D|JUDq#s6OZ@n8JQfBV(ne)ZK?JJ;`D;~)QL?W=$D6`UGkC@XE2 zpOh=54zAoXO+9Eq3nk!k*|H0lQPHz?23JA(=Cb|z=wE&HH~;j{{}ECcnr3cCyEcYz zMzKrPtp7W;iK7pD|92b`;{P^uFrBX~Ci_0yqck8m{SMaweuzdtuJ;-jG?AlVY5W1L z-Y>6sQPgOD38M*IB7OZ07T_BkbE|>=o-mihzvIr!|L1@D;eW;s`QPZBZ{1<%$TEcT zcr5EJzwLKBe)~Vmm0Uoh&<<^a`YQ#ig;o>4FRV4T@W0d5(%EL^thBb)+$?Q1Hn&O} zD;t~Dwbj!nXVsO3C4a9M2rs_pU=)4_PX&wG^6Sm=Do*NfzxML*+k>M8dH)w3X2C9g z+$&noW^;A(w0gF(S>39{TTfOS>v4VaY%7kdl_&VUQs1oCw^p`R&gz?6r)R6pwYXlb zuT(eAs%MpzN_`_-kF@$tO(GlTwc{Gk-yzqv0ov4EZuDEF4$S-|ZRA;^sRqbZ?`^-Y zme;WpJ{!V81{&1QG0tB+aQGqrETmpaef`%2l=390ZEl6~4HWpo!R5>TMZLPdv3>Sr zYjgALbfZzJ#+63Au~l7v(%d?2ZZ*zUpVR@e`bOn!rFr&bePgw;3P5etPvh#^%0^|i zvT?fE)N|p8?$2LStNq3QW@pF8799Ktv@ED_mC|WrYpvAWitAg| z>e=bq>3Xn|)Y*7g^ot=unDyb;m5YFfL9~LQ7N94JYqbDUSNN;|#FH*-NsKBYj1=3Wh;)-Ty>k-ue54ZZgHvCcIxqEw{sW|(yIwjT9DgN zY{6)JYD^HhBym6Wjm%VscM#{-Jf={S`&u6Hc$L|KeCYte*K3(oX2^t}N(94x@nmj1 zc_uqx;Z5HCP;eJ`$$+jmn55vG_rH0u{^y_CZ~y%E#o))c=hr{BDwX|jzFT{K)P8%g z^KP*JcDH)4vsZah-COc#ZPWfxxo)7y!?Onfk`{#9;#{+@z&*CNB7RUY8IpPcuTv53DgpP3l z_h$jFbK(JBp%XoQbpE0KP(qZ&)`BM&UbGs$Zohjrh<<<=!RWY`!_#&PRYrRS@Zc~D zS|s9@Y0!^(NCfe#N^P3sBv*jHWx=4GsWCu)vkUJT3>jNf?PGUAcUt{-(K8k{J-h)N zE^k5QArwhC+0;jRtT&|cVKsh|+4jPq`!1$1QLqr!Wj&{#5LGqa$7;ahp8L9h{1Ghl zWAsVq3%E+X)+xGZ5lDFiCrB2K4r^#r_!45DY6IyV6+lhi65BuHICN25k7@Ji_l@N6 z9sXH}&(6S<5bt?Bj;;}ASiZvR&p$l7(EoM^^6%k_{Qg`%x6k}D&n})H;imnxH+XUM z;^yG!9d2FYr~RGX;fuGgZ}#!s{!Z;W1AbkaFGJ1UJl%ft#*p>R8$IjQ>YF#$r|~7e zc(M1ijAm0s!#K(`?irM3!5q~mtFDxw04K@gJQm zT6wKf-CEn+Od|r=8sv2UGFNqc*=@GYZjL8=-%|WAQ2|auhrrRhOR?vx0vAF=19*@OA3c9jbQT^4wq6As<}DcAKYIng zF@njO$2xd*eXClj;GODf!CT~K$7k*O`IsB_{NS5|{o~y~9lfd@AMWiO7OYhEr_XUO z-&c=!_iJB2-`yGi><@eU@>2TFaj;2b+YvW#fvryf)xTt^rNe9rp6H0&FSr2I1a_Ee*#z9(Gv7+4J06cwEBq0&-&KQhoBInjFkRE}AyCTjen%d;y54 z5A(@trCKdjo|INLkE$yygSfI)-dbDPf@=0-`tg98-~D(&u{||^v9kZu?)t&b`EdX3 z>s82LYx{3g)O^CDd*8S~@J0rKJ>sVzJo5Mp$B;uTy$iN4pZpN_4&OJvp&uf-tHJ#O zMrH)EG~##xr%3Etm|ol(CuS`G4M&MrDb(U6$t*YDN0cUuOv*K zhy>I)cb`Yy*kstK^ezeyC77kqOtAnf#0vMYc6NH!0DW7lY_2t7qgkzPu0Cm0SDLG5 zYt@a-t!i^~V>7NdvKXLN435w^UD-NoZag_%X;!M6ab@LfeXW6a>y@qQ+In@fu~y$~ zZpO{ct*wp5SzL)>?%0U=&HCEv23C=*RdDOFxz1r%POF=hdJ_x6GU^+v8!=wqINMs; zz-ud~PZGQfA&xW{yqq~bW(1kwoBL9yWC0O;wU%Cre#hi7e7E9Hm>&mo%2P~{!9&%| z2slZ}Zo*eSl_&M`LaU4KGV5jNJ3d`t(}FIDT05si54sFGJH3G|`-^3Pgr!|FK!GPh9kBMaf2{TfU^)7DObuXE9HtJ zfm=#oS5Cjjd+04DPOeYR+8ah`N)FI*!K}($ud|tE?8@l{kO-$|<|mE{aJ16<)=#DD zRtJWrVE%4;p9J#4D7LzQK)e>hl(;CTeI9D0IqLXsMLU>9!zhy*BBz$jC*!}1d!3kO z%7vB9%2xD9IxVd{d9txu#)aE>9IQ{Cce}7TvtOUVP~PU-GqCSRZ43cje2QwV|Bf> z_2jhv1Ya~7je4-`g-g)-ta80jsg&?{eOLZ}6@{V`+zQu3-%5*}s?`Xy@L_Y~c*AVM z?vje112Y8IS{xkEjwvV_hXy*d5Ud))31$GqOsN%lb)&kv5dZ^D8!_kcv{j4?D9g&G zqbP#NqIU{e%RibYLh{NxpfrcpwFmP;14S81`O5rGAt*I}hTmdiy+Qbup3RFtpZ)kv zrPAHK-l;C1{o~R9#6M4;{}et6TT6W2EimbMv!_SY@F?uM{l$MN8_{+6&%zh(O6zil z(*=!d;CA1G~H`9-}*AT z*u&Y)X3R71r-Zr8r$7(|UfTL3_8gvB$-Pk@r@yScNDhn9PYJInx;oN;8=qmP62H#j z3q~S>V?4>x<|9A<93AUaWiNR|zx)#7BMipf9?VgQG*gNd6je1T2TT0x?|u>2?|=K@ zfBpHNfqMLJG~!h50&Lk&f08rYo?=)XJ>^k%;R}n2G{$&Fi%PK&h8_qlLLZx|oZ)K{ zlWk^bFk34)=nA5Kx-}gIxrq2-V15wzPB)hW#ZOzVVu*X^h_yh_8K2_^jBgf%;52Yn4MkjN^7}p#Oa{p8Wd3AwIH|cY z1)%K%{27st03$4jd{WSj0ZF%K&BUKYxjpRlQCvLz=#A%d>FsY*GFhD z0tqA+iRnx>(dDV6M!|~#{6Sc^J)J(dZ>hOOKTvg(802vu-z9elI#?v^=S^K>ACy zv9`Y6+&bIZT79xkqQO5I5}%l19Q8;H`*YdRuJ;>AT)yQI7LbWtj6N)ub_Ek>qxc$~ z8*$PdQe~LS-i-X*bz^s3f4&J-9@$0}z*%{tN8*)i)?G2f37j<<$ zHf!B|dZ=3~|K4p5Mr`l{5a&d=vziqs9MQ()DkvyGFk*)c45JblTr|U?-3(UXNyt3+ zhD1S_TbV^|L?GB!L@|+@?TFZL*6j|+Mj%e_+V-}UHbSxiY2-R&n{ojuCn>R%b(MKT z$foI3KLs$91Jqu=z=42FtH7P!0^~8S6AN56%3PL4Df(0x$KCAWKp4fXbx0T#E?9tJ zSx^DPzz1}G!A>tj0!JNeeQnwD$NJg3`VzQ6v!$nhrPMEc&}EZ8$F2~Imk{&CJe3zL0YDUbj{qXdg&Oel*wB{L+|G7egcUtc;eNiSjhtS~Mal=bm&KO(mqFlI9x|Dg*o#UY^TfZct+ zAeb~SAhZiI@gTf@<*tkX&B4_y(Q^Rp_ZnlJ0WMb*tZ9RhB&A-X`a8EEUN{Sv$D)jq zr#~D;&!1`DvZ{AbT+Ri;o%kB$6XEZ25gFYYpWj4(AkO^z(jPc73@`YJlttVo|DN-T z4dCuFmkpNzXPyay(EyK76ef+dDa~|;3Ze!@j#! zmh!uu`BMGJIWY+Yu?hVbac7gRlE*Of1#-~b+Q?_dt;(Y(R6#57gvSj%cTyjYLeItE zF~^h5ok^)dcyLnp)$A&tZi%dd-H;qjRwv6WQ)aW%zGV+3vP5%C%sme!vY;x?g3CXY z$O6xG6ijNQX*HX9R-Sn%k=1L#Jk0*94<)i5N@UH5l0B5j68$0V!Q)3Nu&1SIb9h3g zdJk*EN+l?X?7g?!Vzz~qV@xT(hZ0$zP>C#r$t8j}tX%kIl)(K0LUk#$?|9b@+#Pt8 zO2D*=-fenw&Z~SsBweIE&*p?y3;TX(kXvr4p=wEx3$mhO~vy zk<@RqIy(Gd>dB)0Bv`$?Cp!?~AI^B#JvB>85@fLI=36ciBZ*A|IjNU*zxU9ass3XE z)~mt{OsjZXg1{)i7FsID;L9QnJ_=V=OvJuI`;C|)X&iaXRxb0VY0rJgsLVpU4o&+h&>*i!YZgOGs?YsEw$WOBf#z$i?ZsT^gk@eYs{W zwhV(ZpAh?~)fP784hLArZoIxMM(^ZxY`Md1GK}q7KBFXNQcxJS4-NFx2>_e{%R7pN zxzX;5RjuaWeLGlbrR4cQpJ0_uDIMERTic3 z^1J!431{h-JE^IRXg6>v)!gu888%^cqn^m|lo^$GqPPP<;B_%;W8cUZl;7!ogTGV0 zM12y6Mru*8)k&ddgdG~1>jj#Y1gifV_lbXI$&uwA>gezYNCj~pUZTKANYxQ(A&{(r zR7ubz9$$Dr&GxTvMSJ2Q5EMvQ0ZSDcj9v8M3H&F{^Fo`(iEx+_pd0kFF3IhPu`&OFzEI{h=^8M3+Nc*4NESUt)%VVN!JpD}ib$uQl=i8)6%+y2MtB0gHp6&~%Z(TpfSrYM$h6`YfV2S=A0M=+%X6S9B zZzs`>T8!xz6BLoUnAjaDZr77RqT+k_{CKbci}Ee}AXEqkE6Il-OnAj+;*|obC<(@s z!b3>!5tVc5pb+dmJuVPZ3T4`S5)*(WcCWc25C{iHcM!%Y+!lmazYvNxDAa)4Ws2jHU zHvzJJ!jUKvxssDNpu3W{frnt81|ki+!+smiTf|w^drg$AHySQaArz)_K7{v%41>v} z#0Qm1%uNd+OZY52vEblJD%8<|mE$kTkVOPUyTah%)y{!^ZDVaS4QwU}d&rI=sqitl zBT>REVQO2Wz)R$of&fXEjizTCpuk=S+#G^p9~H+1 zgVa$B4>G-FegzD(Q@?j!FjZ3R*7ZiEQ5qb2PwfI68KpfX4cPtB0!~k4MgJ&kD6VL^i~68MTAo2;lK zm5gH5x?B~GoZpXSoYpsxiB~E5srL2LofL(hOO%BLS?ulb0y|kY!I9jW3j-tw8P;}5 zA4tx9g0n7W9!H*H3#oEsjFO0icbgc;WV;^K3w2K8&IWiZECGn`2&!>|lZ5t%LQy8R z-O+gnRNV$jpdci_3^FBGLBb%iqo&whI54y|#%z#$Yx^PIh9H35aX18UT!&yb&Q8zYeogbH=gW8vI59lATb(>NhYH``GNljsjl zZgeU{@`*dvll;XjAhzq}mCA|{+YzyHr2Xy!Q>VNIU#79BLVp7i;P2E5#04x!z~<>R z2-TDsiPMLoaejgBII4$a%{JGROB|gKwZ@P+zgQ-{o9%7 zWYGxi2>?gc2$h@8hbX6n03%j2eB(8vmG zl7yc_3x*hs8+Sxs4J~>Ikw%vj7mtq3f%$Nc5Y-XoC_(D{(0CyMfZk6Mh3CT(kf#~XbVn))=CX@r#Y|(a8b?y*UO{6Kq^I;mD$Y$nL~-f zSSqiuj|{XuWLfx`ifksoahEFiv0*sc7paZ_s5Rm%L{^>|x5nW>v}+F$(IX0sv&7kX z;W^iE)5I4QNNU2P$?EzLLr&!BvM%<-MW^wEU}6+>C8t*@2^-Pp3Vu6$&i# z0Q0?R2F06cNrvqUu%cClrW!`5LURZZR)7i=^+pLQ^C}49%<3o`AbE8@af4|fl>Au6 zNns6{Phy901VDEjEux`lHgLjVaKZPPP#}*fH^#y`=Sb=S@9p%>G)5dW!1d*7psJ^&xlrin_qz?VVe3W8 zaEM@!I9ydKX*uMe$yRA1NihbTG#9A(WbXEhU4{$*k`eI}9YgFXzOSkX)?^0`jR5G* zc`gyCO+rGsg;xE3fl6R_pCS!_4!gXtVGaM7@nUwyqC*W26MkpPQ-FlKazb)Dl)Ab| zYZQOOW(WZyN7^Ry9A6~12%2_ihT?NZTuE+Coks*OaY@qR_(VcM`Lre!;Z@vgvjv0~ zJ5nl*wSXNgMHhp?RTC(UMF~NNO;97r9htD6F5nsV`6I1gu@w1Qj3wJj>CnmrmTE&v zs-5%4c}lKtr;f{&7ntC2ly|L62&}OK>kZup>e_^C)m0 zjy^W@ikwz1`YPREI)JnFfgE%dQ)TQApooAbun(&u5Dn7ssB)orjqM~vnkCF7 zW?pB_V1wOMzy8yhV5KW9I>8k#<0{BM2C*`YyzsT0$P8uon)toF0_eH5-f9QzEN@F8 zmt9uqi}5vh#ZrW#f6U$s(r6uh@I=$l6;?b5aMvAwtVsWm3ou z!seYuxQ(-S?#Mz#m8EybQ7@OiU{UJduz(#fWK_5e>5_b>i`5%laFyg4%2U+YU@C_D ztEiRS^szO&Uuq{eIROx~Gx`?Ot=y(;Wdu-3f2Gf~iIHDE#iBSoJcJNua{jRGd%`Jsq)7^v*i^afSZ*`tw1^> zkKgKVvgo3k6E#hO6|Fl7;Bs1;sJTOl9B}D*#sV0oz?s5CT-O*lQR-5exJed}=G}Ho zUn5YJ)Vp9VQ6faRO2WNBvRy`Tka`<&f65|2fi#;Kl_Hz0gs_BCB|SJ%5f7!wgRpk* zbP;L6mf~VHf+<5CntvRk9bE^8Kx&JS{6#7eT~m)6@XXvSt1=`E(0a|d0|+aqWp4j0 zoPh^0SZFYZsZrs4jt-djemm0gZL$ovzPXZsw5w7&Mp6q%&QZ=@bRzBM7>E?laKn74 z3oe+`YsG+owk1j1X%0eJzNU7lT$4u(v>y+?-a9yi34mQIHN{Y}cAvL8!w^%_G%R89TN~RcU7RZbE);zq zv*is_>MOwgJ8>&xUoa^|4FL!x0Aa5+O2-G>MKU-zgvt`(+3d$Cu*{2u>LfU>1_y}S zD-Ka@Qa1rh%U|F#hbKujUD{&Q-aaCOn{LGGZ|6T6u@k%k!$ zp_reuK7)i>BjhkTRO7W+r@11P_xq?4$xh{=;8trDv7W)?a_F{_?04{POtc^`&3_UFuNhMFK*pfLA2IYP0j%%?CY( zniE|5;IiZ1eQ-4()DO%WtT%|9hZ+ce*9=LjT4B|0Xu+p;z&JK&t2hy26D+PUV}XY@ zU`(Y0f&un=s?b33T!x}_`=4n4S6x`y>i1@D=4@p9n%N;8*26<_(WBo%uGX2^=Idw@ z3(z&t60eU28nn9V0jUutZ)-iExhJf#B{z$XT4~2Z8!;u^dZhdjoYMuEfjq_tTcF7* zG3Dn3jn}8c&R}Q|xs?$Dj#_Ov4Z@kp$5_6Ok8)Mk>mFMG(!ZbWbe6wE5SiI9@T^ROz!Mn)Eg0y;6?Xs{k?+0Z39Obcn)Uo)5+~YXY;u}5-`mW zFLgKMR*vR5C?2x1QZ0$krKS8oSbd&*+~?XnAYfATc00-)o+2RiSojoG7*X`gott6Y zpX7=J$K`ATc6Da$Ld>n$&1aO4p>18rV?&|OQH1TuIL3 zOxNUV2b>JRZT!am|8AD`pwt7=lERq17 z<}_HW)Fgbg`7w&@UG0HI_Iy=3RhwX(MMaI4K@ZB83Y zbI_68F~y#IU9F68O~b`g_FDCp0y+|K;DKu$&}IQE;ollEc`~S$FHu)*cnOCekmvoS z#e<~G65dqBXy?#A0yjIZMi0zURWwR)wG2!ObzUcEj?PjK5!+nwP zJvuOf5}M;=aVK=jCZLoHcLtF*|KjSRb!6m#P(E1wMg_@KZCoNvFs?S zW;fn~TQqxCT+>95?iDpE5Hp-*bl&csl6G;Aa@uZ*&WEoumw*V@Fmq|gm?U?-k?4BUUn$=R?N{J6sgM3#oM4DnlvxHbu*nX zs6BP3_T?KdEMno35SSX?ELVl7EH4oO1dz-S<( znboo(rSOttA%PrlWO3qQLMmw? z@<|kXfC|Lb=82xi&}a~UoOoFPb-tc|#e}19TxQ0xB6iH~eR-K+_tmR|SI4jSk6yh- zdyk#tR|f}2_dv3+3*20e>QKA-rUKVQDHOY)3)}Np=L5~6r`;Yx>cqr(kNwHXR81iTGNwshZNX9WJ&`0KWcqr+q04&`umjnWk*jS%UD!St zA(a?)Tu^nl1AAX6hEn7l;JUl`2yweG=!bYDOE>IvH`+t|-uGOv`c~W-2jF5lMR<#) z84Nc?u^74rp4LQUJD`n=$0t#DlU)ZWcBH)pg|`vm!2yA|<;vX+LK!MpNX4^W#xcMt zhRs}PcxL5Br3%o3-!lr0;s43#E<13q6M7Kgb)< znVepf!Px>?eU# zl3%0kd^F+0RY1b4;sp1`HjxitP=i5$|Iw638mLf#-Bi|)@Y1PEO z!G|!fgKQwKK$;(Dg)?YbE#!j12Xt08&G@A9dn__Lrm^hKmaib)8g z=x}Z@k~?f#^3b@ND>h(5{W>b+mq?g7r)K&Rx%a&o`=Sl?8ttt3FCK6U!s`aLq`MMx z$s~n@xpL_Wd6x7EK+xD%P;h6)4RG#*We;Ah&{9)7?W2b^Fapsk$R|`|qoE!m?vQIW zV3I)2NV7cb_m-jhEcdM>hNGJgE=V=JsXcbKKJZ0HSqS7n*=KDi$?bwy0d0B2*8oe> zrP)5vhYwx*&`>R}QDjdq-_IzkF$NZYwTO>Pj&ti}ke-6YYyWH2wW@sP5C^?xP>?AX z*I#(m@3e>`85mhj#cOc$BNv|$FVv{a^YAM9WR&aSnfe@pf@m%>)xGQ-l%U<5e_As= zSyov(!W$rG?JQnA(2kyHn8d#G(KWL4=%^59$0_`b8*4C>Ln;FE2~h7DxSQLugJ7`b zC1xI@&_h2uj0dnu4ddMpVp#%szGJ;r`^>wy;CJbR4bpX_v`BdMRhLnGqEDZ+ua5bd zR2@|Q?o!R9Xb@-@({kx;V)z}nTtkwetzs0dT8Te5F_h92%YJxY@9o!K{aJU42_g2O z7h?Y2{P^A1!`jnI?fdV(KC0o5{LUY0wZFFmx>baiBh^Tctg$+K=@4(#Y#?^s4;|Rr z7a!LzTIQNkL9BB1q9TuQ#Z_fo13z8PRXRKHps4z@Wp-`qXLJ!+EFbKXIk-{MUV=jyK4r-(x9y~kxq4sL`jrUc!E{xIs(VM5N zAk`UsuQ5n(_AVKg{tR_mQQDPa9F3C)l9bzjgJ>R>c_iLVx_ho{4%>f*kV)Bf7|O?^ zS|SYOW(p0qsXeY~W7By6zCwzE?`E%3dmU+P}l3SElBuoLp-a&)VQohS5t%EwY zVj@dIHKc$xROK*cyPu95! zvIID)5_mE0p-xA6?%!mX#X_@%0xK@OIYbTwMTw4flll_N)$s~BbsY(bqP`6m=CPOg$!LKmTk zPtyv%(!Gb_8F|HWCj8Ci$RXZ|V|YWdSJO-2s)O5oWN zfEH{^jj9ejFk!0qUKlpNgT17~rt>5RAa!u)i>>z*vE70G^fXL0vosdS5IMdD{g69gUY)$*7EZ2I-xS<%h{56Vwb^FIP zR7-LSaG{3ah%zoJH3^fpNuBW9NLiap=NnGicEkc#9V&RP2ah~zd9|rX67E<8WuskY zr)1E%6z3ygupz`PfkGv96!D34me`{MN(N`#w)79dENr>XLg^67)yPIsRn0HD2CcFH z!UmmA#mUQi$$q<^Y;3ZZ3w@GUL0t0auxX-!94R1~E{iin@}{Mqk1wI>9{6c74S{_5MvDOTeRs)G^I}$XP z30yG&#SDkF%$F_D>+T~Aj`!|n+;OUtf~qzyju~-xocVqv{$|46xlfcF;dTVoMA)mp z2Ve_*r?oZ&LiC7Z2q}7ri3sjMBAnq9&2aZ?6H;TEgA;A?kEesdeOp!u`afTL# zWeX-JfdyA?Zo$U)L7FsG$RoskC}oOLhfvo;PJxKgOX>SQvzZqSKEmiEN(xR#SoSRc zE|h!egfg*|ns2Auxw%AD1IdRAyUBnYGrI<+)Dw;hYJjY}p8Y}~vXYV3hR45WY6pcL z9?nI}2c%_7y2UUqBgP#`7GGv!jLhRofvniWtSo4st5Rw|WB>PYj*H0=(46_z`pT<2j`FN4!6yM6h`fBm=r@9+N0 zfBGN)^H*Q-zn6df7yt6#e)YFsef8DO_50WO$NyRX>fd~Yn0+ynl{U*yP<){S#9yYV z=NN8j1Q{zg;v z`}H?(p0%#}wKfX_3@$ETc9D;9^XAR2RJd)1LlexYMg0Hlz0Gc1S(fjYhJE4d1Po6+ z@hreLkjlPdi26*WZg;zx5|v4Gl2VCORb^GB$sie|LP;`M5e!kv&I0bl4`2fx_;GB& zfB`>*fqS38V^941ueJ6$`z3%m38?(ICB|9bo3*Ygi|%5SSr7Ekgam$8cKjYx~+8)yF*66f7J zfBDPFR`-A(R+b-I$VIk(VuyOM={JJn`0379cRgS&twiITm)^?yT`rDop_IwYFMlp} zkABgA=2pL5x&On@`>%g^y>k4g*Lx>_>Mbm+e*3$7->>h#e)i<2=2C}%-HHN-%_Ekz1V~uc>`|#d_KczRQP|u^~QqN_q^>+I<<=d+)H4`nW?`aK&1Vb2?3d2Oc2#K9b zmdL*ku|nfboW3qtR7ao{u6C_&(iTv2^KW`T&l5s4U%5~E)rs2iYT}0WL!jhoR4ICN z&5NJkS-Aam>j}NME6vBIcl4iZQ|jZK<7cUr+YcAMZruRz1<04LzIt%Cedoc$2VZ7{ zu;JKC$Pxv`s+o{Hr0GUqdQbwh-$<&%K|3*&KJEFnrMKlNH zpuDJew?66J?!$#gk9O}ZbRKoOI}48<+=l*5)AK&|tY0sOWCkNer&-yToUk*CNha?H#Yc*Zju0*_|u| z3@cknH*bj^tLv@Bm+Rj>d$GL!Lq74eZC#?ze{qtyVt)H!Y?{yiCavrL_`m-5|NGzk z*Pnf+|GCyBJ+rQIemRBKHH->Kw+ba|a(iE$r@e}TIZf-|Uc7bR?Hj48bG^4Fb$o4h zy~PFE9#d84GP9Vr!1Lab2kpuDgnDkl^{(a?=T&EEF0=u#f{IO^_S78jRkxT0%&GZ? zmULKYuTUue^bn0j}BIh{|rXE1@}9zl)~&|37~Ix6ic^|C_h} z%fJ37wx0esdE+dchu9tfIL#VPV^t{jcQot&RO~9r3im}Rk;$!Nes4$lnq)A zqKvnVPO>_|W%~jq!428PK4V!o`XwFJ7|#oGG_cPz;R2IPet(;eXUr7Fw}!&K_u3Ed z-?hTMH7A>G-L$+RnUAfkFXXu6uDYi3jv@}nkc@iKV2rs4h1K-*Wc*CDu>kOrZJA;b zT_ip)+iK703%R)&m;)zcKO!&JFh3-KTh^3NK@~HR@~SF*(*>OtaUOvN$bfWJ5^W4! zv4g{O4lsGY8ev={Nq~SqrM6I&`9P2}VHHKJGK2fAKlBItNugGOgyyz!MgXixYtz>+4rMdbI=h*#v;j& zsrg7;OIbIB@P+h1tm;zA22Zs^zUg+zY;M`ic$fO37U(<}DJ&-SH{c1Ovf0$~0w_8f zc}%qD)ujmTSV<=cEgFC)t!iIt&~jhIj8w`}ndth-Sw||3qKEWtHm$52irC|BzkiHJ z10MKAn%<+FF?%neEYbJ^9NHN;`ba+4DIBc5hn3`rR8eprNWf1#1)kMVkt@=USYcgf;jbV zKq3p{GPFJ*%2{ClPps`DTOVIfi#$C^!K=1<Bv2C&`tQT8J9dOdDhzAP?Xr`XGs)|`21xHKu&*5!>$Rz%wSR@L3 zv%v*;F7hcIN|VpFsuQKm!zdoH(+!PPkD~Z8l{#V(ID>Kaivb0Y>o{H0kufqRx`wsj z3P}6=1cUA(gEOP(r{L`mq^r*lw(k_st2%Ju*5cvd!}m}c6k z<6$XWH0&diH>#VqB04_DsV?zwHIY)#*`NOwuS4gAh+K9(NL5tbWe5ggsDWIcR zY#5>-ips=*Ge@aqnE3$J=-AjKFr7xbVu8yT`K0pYr0w}d_E;fsOiW}8!PgjW zmXG$^No8x8jo8t2`D~F)7E0B1DjWBNT_kRPcCuWjvh6=o5KiI%&XcPQb2?n~>r^&` zq{P9LZv&{5;_f$k!~Rtz-H@bYq5Y?%h#0?Z8kVk*8rz@6Hb_HK^J5plO<$8lX<~9+WO*}w)@NXuSjaUZ8m_iyKukm4$z`fEXOdz-K6lj8MQ4D0d z11_rQouxOAnf)(mr;t4_`owO4{l(30=#etd3aF~x+JrXkcxcn%7t=6Y-!K{TKw$l5 zjYTcCEIGGMW`>VH$Sq)=R_V-joJA{7f#q_3J_;qu3>gE_;UDhz_Ff&s6?S@r<_QkQ ztdTJ=d(UQIQmzUIsp17nxue}<)Yy5gA<~lBG{A5_=oE7gBV`PE%yy*UfrY}BU{7Vc zMW7w0>=#4icDjZH?h1|E3mEET9LB@KU`2Ar;wbIIvfT4fR8jF(yp~E3cF~OXtQ=ae zS-l|7du{Tk^9i}pe45v+?M)nS$A4nKc_sBa1jTLgou!(vo~RCDEzMh^m99{z$J(mVWDX2e2rC zqY^}|;@Lb&rP!|9*Eel>+KQam^t}Tic-_p}%o|6gebyFD#k81N+D5)ZV|1ot5*iX# z`%Bgl&rLbW)HMq^-Oizhd|)&^Dp2gTHcpJv%)BmM$R^vSN+>)@kL2ewZ2$gNiz2f; zZCjwc3Y1bDG)@sB!1@(SD;BV6H_SZL-Mm>8Qku8Z(Y3E+TAhz@7{dfiU`cdWRJBg$ zKCHt9R4_igF+Qe%kohBOrwSo!-rW&!u2PFjL$xpKKIco`HAYiLZbxPp-ZvT;2Y)Qn zDW1fio%cO8`=|1q^GNzfDB5$^jG{4XxBG-zPZ*yiL9yvr_~`WoQ+jp97M ztaDqvJ-`(O#5A0f9X)H&^2MKW075{g7Fll}42c`sjSC{U=WFpX(6D6V@K^duVrzmAdp-h+D&tHj2;j??{&GmVcSSx21l8J-^QROfQR zhD=;hffyT%-nnIxK|{!g2VcmuFVB^BpBz_qUGtezbd-3G2&8NUs(V(2nh_w_c#1sv zXLSXCJWztIZ^-N`woCxXgxF(4w9z$0uoR&Sb=JSk?v`762r`guTz3@XWRth77=hv- z-0wXun7Si4$*J7H5t(4;mHmT=ux(JKPDFTv>JGWEVsr^nCxT{dp9FB4^F?ihlI-@1 z5f>&hVCcbN6arzebYd#dA4g&uL4cb3D%h)EkmSw2Oe>;~oxqi4#6NYrN0c{o&%X7S zACheOpq@D-ZG=^N>B@7DFY~{dFJ_5Hs_~8Q=m{}4Us;Szd3iN^$z~!ttSUYrl!WLe zpL7On7fW{(*%@_&5%D!O6mq>$ao7^LYMTqe?gf6j=|$4?l)=kdG?pBS5;W2px~ze* z#LCKxor&naF2umVm2_zGVIFH$1sY7fSn*l|6;>K(q0h0@CV%+GbSI`GOceOA9#R`v z0A5d4EpftIJAE(i>X8vaCwDH6aj6b+{;O{8UQ8z2D@@4!PQej3xa-hbh_6WD5-3h! zVggrkc>JXnM`c(2I))yc8jDQg&mF{W9IW#7y4Gd-rLOSct--UgdEB{sPsyoYFEstN z_|4-d6%KtRQ5KPKOEm-=y34ZV9vK^RV}OJxLu%=TFOT(tW7`b@7xE2?Bx3P*#>Z6y z5Uak_3wKU)X0v^3R{|S9G1RyXHcQ^03q`e?DDim&s{Z!2aAZ;N5ZR5v?GIVh!kl1t z%%+X6ouuwe+Cp1HhlG})JQyjn2*Y&45x{YhlR5SVogRkNu1l0Ehp1cJElA^|1F?95 z9d)&tcxjN7`DGIEbZOndO=1n(65UHDO ztiDR(^ZCy?dp5fat1q^ySimrM909&fflci)JuN}TMZ+vW)^WcJmBiv;P0rL72)^ZV z)842Dzw7J^ktJ>#+v63ZLgk<(1=Fs&qP3dv;Bz8)&$c;&kw{}Bh)&A;94#0zm=m`y z*g;wJPNaiyj>=;Wg0#H8YP`|== zU1SUSO|x{tZ#X)lu&1eMwr#e%M?_Yldk`Cg9%7>1{)mVkQ(%$`8tcV#l-#ixvk+fg zAX&6K+U`ljkl>8o;${jX$YpJLKwU~=0{&bBk*(1Rl{o+sSgwN1m*yGh#}{T9F)wH( zs|=QF;PtHjM7CjV3D}~AQ33RX$OtFw=WZ)9bEAQE(l3}2B~hx6q%3XW6+*# zcb1lDC?qmHYmH|Ie3kC`!OXa37>#-d+`WgxFpaTv$?#<;oJGvFZx%#T1UGNl4s;5- z&kk?Nl48#!LU7w{6MA8qud_J7MY9QILtWI}EOPmHlbjI2j#dHch**G~7|9LD#%Ume z+zA@t)6Ql~b4A>o{?IU$Zg5$z?^H=6man;kn4kdI9hyCraVf#U<-4NNmz~Z`6DV$X`T257l z-pa+mO1tI9h_LB<$?P(^01&yfKM&ufr}Vz7B8({(9E||pqkayEN*5zB^Eg)hVRxJ} z1oUu7itJrPG!9?(CFPUzxCrS>gr+1IJE#m-$Eg(PGp*AuWu7jJcSJd6uVM{Y8 zW9ZlfJ(Ap6GMt%{=2pn~{)Xom-)t4=0`oDI`L)Qyn_nDBQa#*jsQTe=SC%WKfL2*~ z<8qy=&e0cZQ8gtXhtrgNQ|5Mi=vI4_J&&VL#cor?$G;StaA5u4U} znX0_^G$YO*bVFz=r94)&7`$D|P};cVQ^|U_5DZs72fCCS5k&5o}~5+}77|5jIIl`E~a$q{aI6zrd%7%^-+ zU3@LU?$T@K_bwE`;RqHlU+kV>M8ApYcI`_@k_qMdxhp`x`SQI>u3j+qCrqJ`Cm3e1@nW#C2BZL zQp}R;C^j!33|tHHX8R-nx55uI&`oasijZgC^oAn}-uu8Rn;XVfIE^@svv=;;KrNO< z-krp~Qu;y!%X}-qOLoYla2Xv!`^^XIC%WM%*)x)-q_c7B;r{Br35$z(kqzcDu{BE{ zE8?=PfEgmVajKBZ7la&zR96bQJdOn@=~1ifJ0;0W25xnJu+d`p5~pg+YdmS@BJ69m z&~#(S$(nj*?#V|6Fj}`HEe*?tCCvTbip3K^G~*~o05eW zJqgyd?lOQYX=yS89Z}!RtXZ;lk!9-AuI@VZlqce*9LQ3sGu5pcv!heydAAh6G}lqV zU5ijKQzFdbP(A_6mTV?{CJ$E9{QQc519_y^D}3KlTyBzFKER1eJQOAag43{fKIs!_ z;X!YBk*%DFOnCn?0ydfmFw+(>KbTZvx~6jk=vg~i0Rv$dU;sj<1;|luYNvk|&cJ7N zH7f5f@qxk<N0M z#B7Dplo*1fX>F#F3BMNz1kMC@@zDT#ZCr+WARVNjL)uVvCOn(@1P8W$RpdBm+-fc2 z07-LY5#2UrNz5ZF{(e&~>L@Q;%5xI=;A4hfeCSr}?ja1Ke<+rcHNWJ6FOMvJ&pdW; zoRQ*eMA=PC@YWh8-&H{cNul~r7>UNH&`S?g;#2)qu9hN>2QB2|E>V7LFic>1{Y)xy0y@`4Rj$Wg9YAb4ew?Ss&A+`3`%v!DVV z&Tj!-pn}I=>hVHnb!WX|S^kXApgWLm{$uME=YA(DzwY!Xk%gg<=rryf-41R&f%^L3 z9eJ4X=x|7`98FrNH6e$sH8)=4Oz;O?-XC_4I&zywpunqlM?{8=pJwXFjw6{-cdP#8 zy|SV#aJqPP4j;At$3HL5KV6vr`p190^S2xG*@rLx_5RJj{r8ncy($*4nu&!vBH6AE zJ702_*ul>ZeRkM6cW)C0g!_SollP9udDKAeJ8CkPEY+>BZa0kJ(^z0uiet!%Xg5Xu zO06)PKW+nGRWwkZt8tY6@Hbkg!3Wk3jK$i?oQ-V180DJNuE#_1Y9POZ9j)E4&37nf z1L?NGtseGvt=5n)kQ-sfZLQB_?#Utj?J&tvON_CXu$299K5F39_A8g+m~1OfiTB+k`{Fi85FC=@ z39i*MV{5n4*>153R{F0yQ42dwgC)#72gP+gyRBE3&%L)I*GD&(g?Q=Y9qx^d{9gMW z;32nf-lC zeq>UA!TA*0)<+&28Gk;F+jRzT!usfS%CBhTswZlf&?cK&{Up=1?lpupOUm#k#;!Bu zJ+S$d{NzI6)}T+Ew^SDxUk{bvxWCc@O1qfytzl5Jk zWxOfv$0&(_RM0VNKYS^09o!>de1Q#lhZ4u?!ptC{szfBge!`6l8+vpvWdOTe+ztBzBd#m3&s( zM{u*lj=a`kO58j{$@M7cw4@^eF-~*1Ge>ZR960F-B=r~+Q3U(lkljmU&**53J>I^1 z=YHYCVS_5xoHYwG<@4f;iIz(A2%THcZAyAf9^dFWfkmEYoXqNLoEHn!VQ02zjLd;sx_4aM4@5AcO2a5m%T-TIg0^Xt$=Uj0=#s&DjDA{!B_=h|MqVcz8T#F=q*7 zTKqO4%?gy3uiOWc$pP!);rtglLe@rcZP*2|uY0ZS!Mmg5K9~SUcs@MIMu}Vz1 znseT^l^M%UIoB!rVvT~d*u=Dg`9dejHeWn4rhA9kPW!z!iHFpcuQx2Zy=MVC$d+>H zQNl~s(3H)`X7xKKq)-)Xt%#u#IgdH+DL%s7E(-e5KC+?5?o21Tp!lWFx$WvR_s%J7 z>WgMRC4!lynL}RTSPET(8e}%_L2VA6o&4(|d4;7~?4<=fqoo?&zQ4@8{#?>;; zXPa28{cij1(RQ0bzD!3$%X$p=>dLE*oJ<;T4+7CZ3r* z)GTfd`}-qygo-~WV`FSREXw3s9SdV(%t&){S8uf{9Ub`UO@aFc|+4{i0 zNSwv}+HodYEn!1hZWmq!%JP`60ZY3Eu(_)gR&H_PB>-oZOI}NF zv#K*itI0BeAxs*5vYM4hoq^K{{DT6=nSxslGAz${!ju7q36KVE8|$Uw!j(5*RQ($O#+Lwzw0YCd%3xy530AwyPNkQ_Ws@do&VGDlQhun~|?= z1b!MpLyG>9^IU{sLYxT9Hidmd-x%cbvMe*!xB{9CSesr{i&O}rH)ShPI+#RNOL|8* zBts_B4>8JMXmN4!z;v;T%6?0~*`S?5E-a#_8v=IvTd#qMiVa>-7_|*-NugvlUwlMX zL&SPw21}}3;|`O!nsynKy3%~{XF5pPP8qYsktOFb7}_=GAGQu(5Grwk@fd=O@Pf5h zfU*?^0-{ieMZ3sIJ>#c3#73R{B7>}^j25Y!I>dGe&Ccn`q6|KB*FI%U!qlKhhL+`O z^4+AYP~&kf9HgB?5suyrvpL4Mxpk1T?0jdWzLiMQa3x)auBV$lYj!HNt~&tLfNQGkEjP8wlHIR9xIA*P7xfimjl?hHa`u61y3Gqp4rT*o@Uw&%(Lb z-?u_6Y36?y#LK7-ZOppXFuIGJ)5*RX>!0h<3_T9+b$-;0+9a-wC$1`tH<+OJ8Ebjw zHRDfTDKE?iw^Lz-PU9Lc%=7uCXMqhzZYqQ9``$EFt}wnKF2gA+oI0m^wk1;ka_d#k z`^ZV$S8xW2@ zhz}y7Qv3~=QvdF{9kd?lij9`sg~&#snG`CTNK)S~GciVvGnfWhrSL7R&EKBCKY!=; z{2dCs-MRPm?K@vR{A&KrgRl9df_(FL?%u!swNTI>%->#E@cMjd{NtPHqBHnauG}f* zx`I}nHaD$bx6l9Ozx=oV@ACbp|Ih#Q*=PFS^MCoz|BL_jvw!>9XP-SedGnHgivQgI z?7#YqV78+^$yW0Z+h38Dc*w@TCC7TyGQUMloROdeZxIpK+r?MVes{3{a{b?Y_MiQS z|MUwU>EnGW@GV6nt%U06)kB7#y99z*I{aLXQefZ_dYSjwHU)0jPCa~1nF?GH+rzH# zPE?m z-+R0I^YY2c>mTl~JX!olA8G31$8zE}o@%sC9(@QpFkFSX8DuNTV8~?cXZj{8)U7CA6-_h*6z-(RkC8 zFEQ1*Q>HlQLEw#3%ZD!JtA`#x`paK}w14>vVKp4(yLbNb7cMQ;jT;i&+|3Bho{tP3 zy?g%M_ruA`U&y;A#mun7$N=U1W(LH3_AZlc(ulx_)wi&S4W_Dp=#IqCT#;XH~*&h^E~Ot z^A&E_uTIqVeG{j$9|Ds@qe|y>%}XubS-Aam>j}Lm7rHyBGMQ{+S~H%luU2k9T==?m zgY;4oOuzc-!QJ+q2M-^7nGwRCPqTpwdRg_>h_f|;m4kcd3t=X`Ca8c$09KBY@( z>SvRwHDUgZ+^DDBTfHRapd6GJ_3qXuz1w}b@aWO*y@k%BPIqVF(SzF$JCDBp>dsF6 zL4-QhK5ggQ!pQ#U(d}{_f6NYUT93)Q%5UB~B&u$0J?zeR@9!?m-+Qp#nSc1;?)~|% zzuM}2#Sh!t+nsDQbL8)iPq7XRbhmj-IYOHV@1SheGh)I6KW69Jqy}QB5w?`;rZ-b^ zN86T5k(;xyJ8g#Lr$<`<^nh1v81m|kMoGR#*f)1aC3uR zSY2-|zFhzA*^A}%AF@f!r5(Ta11Wne`7cgPSCno)jGjLKo21~suKx5N|JTny`%M3H zDOhrUT?P2>CP~5l?cuFL$ek=j&z<)Ei>1XUD@*NzouZ+?Yc08u-+I#B^-) z^5>s>c24;Xs8Ya$3C=rI09-G;V`_mS9fixK)SJJKFr;`sb+vg+$$$5EWC9-WaLz+_uV9@&WPJbJ;^9V%#@rKavhmUUEIypIMho(YO@GVN< z>~wE+iJ(l1QXtCRvSGGg9UtriJfv}aFExlsdTlRlL|Lg)H_VNgt)X%Stt^JD<3idV z&KFnk--8ma%w{Af%SbOFF6dk*PL(x;@o8o{X-cAsxyC-XLdQz-ljkgHU>erndHo(n z#^0>ZTNNTG-~0TRmO0m2zp!LQZZMzLHU3{d|7CuDzW5&xm(q^j-~>08Z;YZ@^rM-0 ze78o%VT%{gLlyC?fv7U04O_($2-GUdFcy$=ilnZUQx(K^>qW793rqmH z7ehCOh9ZgRTqxP?qdwW4@3aI^EIvetnuq;CG>lBI`UI=x_N9PNP?j4{_=|0taX(&D zAC{)3hkt2kNHdJylZ#eaZT|S#ZDO{fSv4Y;pgY&n`^5~yAbHx@3@s^I5~K9CWJaw_ zlqaTX%rD|-E}{Kw7!C@V)q|3=(^ zyt}M~UU~|f0Lv&1*fI}1_(sXwEQ<^OvE@^>9>G| z9rVDGOo5_S1xp(*Uy$+U0d#}_8^`?(a8=mKr%lGtf`ln)kDfhrB2{-cf);o+%BH=R zSq*3;qgv{S_s{OdW1)$n1UQdAbX+N*fpg6Fr~;)U-`dtF`nGMWG!ElaRv-f7t^J4> zS|tVQg9uqwdHB$u6Adn^r}^mJq916AAI4qv+VzbePo zcft!wMfDGa@7%W4)b^Gf<@SQeWKic*<~;CdzR^x;K5g1xTIECM-^t~>W8+u7b)D$t z42H({n$^70&wkpeE9a<<&dS9l2PIi_Npp(*H`Y0YsfdyeJYpyItbw#8+VaX%b^D5a zpp7|bt$g#sP+bu+rl*`H*5DgJ`d*`(x;5I0kkJAI67ex;o`LZkpnIVpTQ zhFN?;-HW$E1J^badG;B<{-#9ixyPN*fqns8c1Vrq9#yt8dUKQrD&k83WU^XV1*%86 zZ0GK|2!&yOfse&p)6K;tuC~wLD(se6u6^ulCHbDkm%bq7FGYlosCb#Fq)sgbiRo1O zvoB}WRrK&w@d)-egi52YV@cYKBo~~UibFY!SeJ5>w)`vk>HJbfY3!-cw&K~+(N#aw zZE>=6c$Q03+zly6Zx+nA>~)Nbq=Bu2;Jlyj({gy7y*-tPcR4>Q^r2`ZJ@Yqr8f zNZ3WEP_#6zGN;Qk>X|cUE!VHYh^^yGFkXNEGK@A_$T-7O+q>zDi!oMj^?fi>@9DCP zGg?VJt7M0D##R1ue(qK4WR{H4o1Qfz^i~spDOu1Z8Q-*wE_FOZ#&$7AhSLON3KC7l znz4?6Z59E^->%rWp|dPkBHo|$^%q4e@f7xuo|$PBsb8^O$b@BPT)y_M$<4N`wW>f@ zYmwsi@lfh3y=IDVO?s=pY$gK+?B*S&q$?DuQ<|D2DN{RTNWf&Nc=FyMg<=fstmszp zhAwK3H;&v=2(e*rB)M73enZ~ziYA6oMY8Z|hUvJ)8sRd_l`v0tF zh7?TbTmc?}rUI%J^P?mjsLV~I6&C33p<3rUft{cqT@m!%I6OLair zzxv8l^Xa;h5f@Xd8K5;2@2>pTtpPDZ6<~p6Vb%3VG4R2I&0tWz1SZ%O7ZmFGg}13sW;81B4X5*@BHtUP_ zqUmoWaUz>d`f3JUfGDYzXA+b`)*sO(-xKL1yB5y$=S$|oX}1=sw-YbS&&wU^kNKN? z6R!1i`4Vk~xeU`V9)5!m2VcO9Ijs%_LI&9LT#7caSj~A!7oGEY%LK>bhGQ2Yk~Ce5 z;Bx!|x%m+csX}BGlurzK3O72v1zy1bf2ZDH>1|dPpM;ACwP65$wR~5scOJDybW*qb z&Nk1jEtJ|@7N2lDk1S>>H@67py?1Nj_ANzTNp74EVQ}7QFt2|2+G5&H-#jUbYQxqy zPFAs1XSGFL=9f97XgYm$=`NCaXNKmMtjTuDywR>?{|yEmpeim>!-NJJHJ#8Z{!|}3yR#8|6V=c4KsV48Jyw1L$?xp3SMNif zpMhm6r%ko}nM(7gbn}T@s7|BI3`F5mn*S8U$Wx~O0f>|N=x1#0ZfN>SEZ=AMb7g!c zC{~+RR8rDabAhr)xjy(|TEwSVkUTRKI$g**K1Da58vmKFA3sb!WJ;IRmDyO(o3_i< z*+)<5?P_eL^$y>Yq@^8K>*_YhhC1lX8ojd%V8*GZrWt_SXk%XFX$MeTtV= zZTEbD7nN)@)7fI{%WrQ^X_uY!?zA@AN$*c}oV zLwC6$H#4B+Uth-f+R)=w+IkzhOJ>|_yYG9j`!>-3ifzCRJ@S<*xS_yZsXe$oAx0we z&0j3&C7;rSK4uyCGDUY~z)A#DSWZm&?fVFRnPQl;2!NTQo8**oTBJ|GB`w0~v>=#D z2cEb~j*g`5uIc|mci>q3VuAKu%j5R!grRuGMma+6YY-QP5FD>*4&Ff{Bh2J9p+xl|8Z`D zV`-`(hbmj7p2axq>#2u%S-KgpLok4`CDV_SDY3k=`0di%O_0eJpFdxE!e7F>n0x+W z`S*+KOXnxe*1O~GuoiBWg0DQ%%Ab&rQW04M6m7930p`Bg?uq`&?cCqp1;c~Jp7|ea zw#O5HDf8EKjXn~ulI5NDj?C@c|&zJ&(0#p+ixoA5+J>mxrloaG#!%;+RB3k(3|Y!Y@S-hK0Tq(<~ojqT~4l7nx|;WYTS2KSjw+F+|!zr;KCf zB(RK?b(o&#i-`UC0=xqup*0whw=%mOoEE&KL+HsGKs7>QFg$Ku#SoH^^b6CnNb&3h zmA{>n%ogGs$~UDvvO5Iv6h1{pjes@!#P!75MwGAdB-pQ$eZNZ}u$s})y3i2bpVD6C z&fzCOl*rZfOzp|PW{0Qwo;ynGv{UD+&~3jjwSE!_uJ!ytC3_$7UDIrc_o(3sFvtjLweDU4W` zvQb4ZkhQc=t=Mdp^PRp6vBzhEGH#Z(tFl4Gki!17R-~L2#*Nhfg^Ww7^*|3;vwzPy zzooUM7r!^#(&J|>22^ePZJWg%Pea zL_Qz#khV{EXN@fM?f}H^_3f>jtqDKOf8X1C1t6(xbWM*44BVfYLcvIw_>fef<^p*| z9XvGSZnCBnvpiE>Iqrk+&~{{DT71%{3Yr&&(+{#zLx3q;=|XBxU#JQ*)`!Fwe*oKI zKuw%!?eWnS?QVp{^babsSgdRDv#q9gh8jQZsJV!{0}6H6$Tz%Iwp0GC_tkDaJ0zvY zUH$TBRNh33gkaOy&wNtkfq-W$Y>L$7Du%y7ZyS?X{F1uO&^#iEHLb5=SsI%&8yFP$ zZiFQep4Qnhq>F~8&p2bzI=11XqwpeFs&*1qVVO^nlwn)M?!br0fFj2n(lf?ELl+8p{PFy|?n$r@+`ZcO|&ojW=^<=g2 zP`pL*&Yt0f4=KHSEQ~xhb%71pX#y$DmAw@=^P{(rF6If{G^|@lcKjhJUIyS&B#50c zZ4I&joc+FgxQB*WY<9mRZ620!6nTw~F;phDr6_NV?1Oij4J!yU)e!V)YXs83F}Gf4 z|J@MwPrl=;{s}s*d=rTltrO+(GZWR(^)z+S28&!l>=jEI5P1q$LP~0fqYdH7L#=go%00t;b-T035cPk}< zRBjiWSQ+ds=3EEbJ>#ZxH3>g%c}KKcYkjWu^3I4W;9Pg%3DEG{odE(4h~+goT5LF> z#EqApOtDL84M}vuEk~`vZc+8auTJhb{yPM6TZl%4NO%aLe0WVDL5q|0yoQ`LasI%a_YfZnmhCcEFwbJQUV%`4Z8BJGfJLPOT@0 zQbKhJPqbat3Pzxcy$T0#?H8T2DS|?I$N|xDy23lHz5V_ci}7w8kjV_vwgni(kzm`= zMdeI8Ko$|CaO*jlyMr#%kzRe$)smXGEscZbgIL>Xv$TLf0yLRW1onX!9w-77m~79h zo+#n?ELE$No!G4xL>8`ZlefKNWF|x0(;h%((6aHlDmk&^a+1DcN(5#DHQgnX(Ff&mjf`Jz^tp1$AKTUX`hT29d7rUZ^d{2XAjZosggKl~-Hn5BIt|zjdd!Cz1i?JjR|0O`O;EGohLD znu2Q0H2A{{z|?h_=4JxYI^mw2LB4-&I`1iHcf8m46skMk@%sqS9q$#hzK((nM}-mn z*v*7kx;PZiV> zQKSBZyLRv=?#o*z?m*U9QJOrB+De_{6eB;GAq|f@#3H$0)DWBT^rTi9)FiJ>HYAVu zx=f_zSYu`6TO!H(63AAmi9m?m5HVfU@jeO_Z+PUvO> z%&}OwE4h~VDTgEFr+1YcNj}MDG8*p<`lBPPjubo|$Wp!8&NFl)AHg1y$voaF(GjGB zV7->zSt%K(B}%3hvl%^)WRso&C!S%pHnTWE?WD1k=I$?KyPu*zOKAxAfE7|PLwj^@ zKRS40z2JBvPz>8j7w%AJ+?rA*JoV(J=sw;Hw!ThnZ{F0W>F#jyi9qNp1N!Z=me$jv z>?1ZGB?5V>f@Wt(6r{++6r#JwN~+%<0&%J$@v6E9H6PiAiX0;HXtoAmNMHa1MAZ^^ zdgS%^7)Z!b+b7*EAnYg#8Quqc68)ntE{W;pGdi+05at9P8iD4;Otg=`8y1nvokjpp9>n&y&zB<9p_qzK>m;Rupocl6B1iS5DJa6+2CXpquyQ5`Rzk;q^s$ zH2gI#!uRLpeot55$8_hN=dyD@@i}j~%U*ABKV3o9*|KFtU~=QBJh3^5RsYz3RdV7s zS0a+lO}^q2|J9WsKI)c$d_W5f)6`0s^Af2WT$B$9s(UH|HlTGEgc_$dlu78`32AB? z-0o~7h$up=VgszjUyU$6CT*P|nB=V*Vu(kQ6ry6R`xKI5y`>BXKhWZ;Q25&C(K;ab zNM~-~QGteY?ra-e>TZKTkyPEG0S>?NEGk6EbpcyfzMEm22Hsy#*%SbC_s*Bb9QwdWkuYs1SqP^YF>Sc5p!LnxtM1!*z}tEH zEE)Cm(I99JJHrD8wa&s#(Xl;0>>e0slM(urV6+H*3m7f-tbToGx!>p9rUm((m-*N> zWPF-_fX0)02M67qp3>}%%fhrk-cp27zqRo8_QJwV1Zn0y^*qGK5#cqGixb?lPGTk` z72S$2yoN-!)(r>e6xlvo;LC?WjWssgFsRAR&oB&XtdsW|1~uOMEW)79YIP=IP~)9k zWf;_0Z$*gC6^22b(rHa~y#&zRX`ReE4C=JLE)fPb*6a+!pvKz1sxYXrjfr^a_llL1*7F>z2~Tge25MGc+TelqtQ@x&eF*utI{Z0ip*)8ds?>odODIg5dV6 z&Y=)K1Ko!z9FpDvE)p`*ruU0EyS3Bjp~L=hUA{_BAY_a~HJve-C@l7WE4sDA7h+e>#4C z)!jc5nj+K_%ullG9-s7EPeDZ0un_s76lW09few@)DZyUSHZjw&V3CZB06;D%c z79w(qfaF99)GU7&cE)Nfm%;x9In;(fqE}LIL23f(S1&7C${56EXU3afF(Z@wizdo)0=^{y~YDj zCrx~v<`0j_Csdihb8mr1Z?+bH9&s$nZ<>cr;{qC$L2ETZ#j=rnQPPh^e@V469JUj9 zR7aiMZ0&6y8P#@rd%fchT6?!+y8rm{J0d&1y)ayPEu5b@<2$0!O^iwj9FEI0 zvj&XoVg(Gd6E2uw@h!v{o4S{OgpdI3?se0$|B-&3Fv=o1l}ws zaq0+oJUVLe?HEj3(S906`I5F%y(59=Z2(Bu?HsiAw^s>#qMCdDt??>-o8G1aG0NkO zd^PfB^dR{-W`@ceD!$hk&TJ((U*3Sen*1&oU7*0V_qzS|wh#x^rRc`r#rP}3uD=9< zVNXoXtSFc?PWtov`25(>_RT;ZXW__+ZHv_QG&s(QI@7ft<66y+NNQ|sg~rARzZ<;U z=nea6l#j&%ar7;(J!`a?;8Cm6#-A_96R%G*hh##7s^8<>?j5UgsIHlP7_2^M_|SjD zjJ^g2S?@h2|B|CPztbhd4691+^MmPk{BUvwz!ThvRp8MBHFr1yUQTNYSH((X>|?7x zf-^%22YJ->WgYny(i`}lyUo&Zx0o@ewY%SkBVbP7>JCawK_AMNa@1I)E(HhN;xgbccVip zyaLm2GGkt(qa5n8gocM!hu+)tzqx}{Zn;2bu8u^w zS>1hI8$10G4xniUFT)i|EcbfePx-Cib<{WVrcFPU4vgU7L+WgSddwHBZTXgj1_`0k zRv0bw>uvY?Ba^46AKRr0-k(9+QXO7r1Ex=L&)8&5mmRx<_xA;=%T}<$py_^c+F4oq z^i}d2K^K}+$y@%~?-TN9n`=CVpd7F@J!5P%wJvF7LkW6Z2!rnIE}dGtA8ZO>1C2iA z%d@_$m%TV^?R|L3d=2~KqrdrUi}qW;^%VioJ{>7ut7wl=ApKOtu>8R@^K$Zs&&$(>VtlEKiy(Q~dsh^V9Bt?32muFSGoZ>+-AW<3P$@OjSM!eM_0mSV(6jc_ zS8>N*sO{^loA(iH91D3>IX2O}%hJcly~P$xU)kBb*gm0(A{E832%;Fo5to2ze{OYU z*i^wW3asE5a$ke}6xGR4fTR`SIy{`m*u*D^@pv6op#;-f>xR-^P6$Y|QYj{S-@fzU zOPSpI08C|1mY%7?tcoO#ibH|Gj$*A$TD`r1L5-4)*7jeXJW*-9Z#vsQwT9?8uVkjf zVD;A#Kwr4OifSLx1P)T_eqgbq&RS0<^FbHE@=&e@*(|X=5=hr2-=cgIrGRrNjSf54 zU+^FN1>>Ne{);L-s-TKW!R=e|vx>Dhr)yZRMOXWil_Kk+PkEdgg{#_DcYD}QOyHN+ z(&M#4>^JSjOOr4_RGtHr8S;uYvsX4f=yuTk>xdi=a-w=&lqL=R0H3P+jLkR+vX(W4 zvO}TCLtAgFT2n6xV-?__>->DURb)tv{zabQzACR`A1r-n*`Vz`8@P`IL%LjRD!*yo zIF@ebwMIru;-y1$U%{3T`q5o}tNlmtm>SkXwK)m1TW69rZ zEhZ;%?JJQ`&k>MFb8`13FRS!P|CW+IJVG5HwZVr1z%02s<#&==mSLfF^YKn@3mC$!-s^r*gvZ8s{kzg7L4DD<`j0J0@U%n`41HMe4>GnV40|v z$PNj-N|!c~XvE>#)l?vKQIIM+GXgcPHpT*0dO0em^0;CKqz;t+58I{Y+$qCm+FtL> zeqtD-fr37mX3M`(0}LsP5Wprk@dM$VpyJuSa`c!`JcTFhaBsxp zVhqF!?Px`u(TSb#C=AXV4ei#Vg4?n7af8x;u}Y|_-ABo5m91_qi9nH3ncp@x)OMU7 zh*13;%+H&Wk?@w;7YlQuPt+>S_XaRv%f950rRW*+zVrE=PR&v8sH>Z@zUIU~v)ibT zYR;j5Ru68vw8O%JW?z*avc#7)NgEWIx+XesUl9gllTTt*%nIoT0~N!h3hT&k4s+nK zVhTMeIwsI4KqJTRB@MpJ@5DDyEv0+t-B=+o=4wJr_uTm)l>Cl^%HW`?Gf3cM!LSQvh3gcT77ZXw9 zT(yp{^7c$jvpdAD4xPj#747$}tgSVV>}XZj2;R|=;wNet4+hYHKTUvS1!Dw>F-Zuq zf`GUxE!fH$XQ`bW7|S`f9$&S53<)KL5!rue`QFF`M8NS~2uy0sa$Q8V)RPInMIGTV zlZkxSWa|zjRw8fnSa<&uP=pq7?B5BO1#`5Rt(Z} z{D;GlRb-}~pnNxWcYBCI#+%}BZNDOnjF5o6NZcU?;U^T4pEwfSsE=AXC0hSbT>qX7 zxLJOamIK)dXG-;$lK<__5(v$IFDwGRLb_+o&m{w?@6DD%4M|+*eZptZmMRjaOXF6Q zGqHhO0M+3$dM6nk66^d)gm>+!ltf)|(4FE}tLv+=T2J8|g-~U}rQOqZ&H7RDD{OBB zheD7->+_DCV{oA#4|?12m0ut(qNcmr8>#VepNf^@W+vQGqKI{D!^%}nNQz=>mOB}Rm8r4OlyDU21PVD6ht#|WeRw$emPLq%VqFnbaBIOx*aw^;#(~5U zJdL+(vvNqeqdO8}6i#D|W5E1$=QP9xJ57WARipdjOQWmUp7vaH5}bF}Z?(AMOdzt* zRlqln4EJ4wV>a8}BckCDrOX}W*WdnVPxb~lRg!6gjyy;GR15r#%h|7wMPkorjw3eY z(%8%gzM1rVQ4TYP5ycpMT2k-1nRl`Qb)RtF?Eb#Y$u7)ea(dZ(m`Yg`_3yldx#G1j^B4w^?Wvy90{5Ggs^5gjB$jcon}o z^JhGVig|_A9}YwFgfvOPwA-K%>3!+A)>$HN&^B)JqGwyYJg>2WY5wqAf_q)8W>YXS zg1fSLAXN*^L&Wi6rrQX~MRUYSuiCtvkQl%Xh~!gn^4Z*CgWwq*?H~6fpa;wLm$b7o zK2i!!X(o!HI)0_mg<5N^5>*BSyQ}3coJ$#y-jglUREuP4K`al-@YB(NuI%8(teJnV z8=7SNN-+z%+lIsbw&KJ zQ{-aTCInqRp3?g+v@xc1xKdsM`+_?$5uK1rLH9JtB@iKn9Iu%!S8QaB1+#>a%66yo zniTLweP^22n6ye&h3k8MD0LR;ZBi}uT(BB#q>%rSd$p*ClFIZ%$xrn3?lC+)*2D>E zrbV9f-R3;YYfY1sdwhJf!`@<0wpCHNhwqTO4$`EgOuLdF-{1HN-$a)?V5O&e&h$4Q zQ<(=#W~4C5`NffBmBT%YK^vFs2EE}=8!3|G1s@`AfFhp_7d*XK|yVMqv;7eGDVpog~?IA)q>B!=)Yw1r9&8+n8*KqN0 zJi#V4umR8zlEPtDuhPa4>xL)+&#%EC}WsRL1z7Fdxo$`Vi#jZloLMS18HcjHDHoIM6eGr`bY;$hr?f#Khrk^}5(Y8LZ zh8<+$@eITb_&KhJB#9fXG7IE81ogTpQ$251C5dE?i&UC9c+>pWh~T#4Ia=(X{F*=@ z(*ZXR!Qtf<7*kEw!_ClSecy6x97>y&IWZYNZ50qAL~BSzBsSmdx9TCzac{rr4JiW> zwnc3=_`%hhCViKPNER@b^HdqOXHwNXHB<|Vf}30>ymvyYvkA4D)Hs^RCmG;7ksg-` zRGQT2M;+)hY0|Ke-)xL;F=lQ_5_V86J+2srjsZ<#jhuoqIqGnD;x6{AwJz?nAt^{m z8Jh^$N>9&uIPEU`jjEGMOS154oH4d7^T4xmhKVwt8T)={|?vXG3nyQu_cU~ z*zYa0OcWJx+fE;+^g$9XY5L$+_i%nRymjI(3jKTc&Mo}9`?u8Zy!xFly_$kzCABYkEf)X69m@*tW+~ogQ*^#>-~~Vx9f^nc-Py zH*sdrR;>xMos0ZSGNNnw5h0V|)Guq&mUV~v%Cpiyiy_fjJG^%o2495q#-`Z}B%bl$ zs^w6bpf1y}H|M7NN~aYOr@2XcD?z!eOV;L+Rm*9p6Pj(hf{B6FX;4QSxS7x)eW$6} z@^gscdP+7Z*@X&{_?B~lu?>9=zGSwibcHgioZAg+?3dO`_ZUngEMjE<0;UT^k;r@u z-GBehqKqth$4E@;lXrC9_yzX#`0MA~)r}3DcV9O)a^9UCsi~-nmbr>bQd%?$yGz>6 z+H{k5vNv@Ba^^3dlaRGn&r8DE>lY(l3jJEm9C^|3>03M=!XK3~6`z`i6HKfUBhVj; ztQqdK$8H|srV$K-Bzjb(cRyo^#Bqbt-p93TE(42JO1T)E`FF}km?&e%0j~{-1Oi%i zr8~KdxHXmIjHT~q%nx{!cPvS#G@sVmuSvs9lQG4{mXn!AEbPJw zH)nNHX301ay`%Em;zH)SCz)rq88>GQ?ouf?XElyxCc7ijr??>y;Lt%OEs3Qx?uTN# zAxa}!I% zvq_#c!nVIF2<^PB+;}-%JE97mRi|rTn(@%p_wkvYIX)Xny7+OoAx^-i%w%|UM zi5v5;BLZ{{u3#g@DM>uBxTfT*(WWe)!}v4A_c59GmXD%p;Oh_)J^vuf6JFuz|Jse^ zV~R-SC@AbGk#jtZwxD?V-iD8a4pJs(VfNFIlLHJbLH-HrqkP#tD+1&ZZSoY%q9@Gj zM<%gNoCjTC0+r_o%U&)oVrUANw89(cLI!XPC^8#!0q|s_QuGNPRrktSg=8fYtx9bhT>E_mKBhFxRx1o!M0@pGJmTAT*H=FVnj z1>}SDRT;mL@SV@tYNjU)4Iz9T$^WEQ-BmI4pd~yp1aCt`f6JN^F^U)lTbIr;lmfB} zWg@HVXhST2!qrzkrsEqCV1`^k_}Wnru-*EO^-};9JLGV_`}S3buw<xy^lV+jko zDJwE>ci+k@%AC!4n9PZfFnxnx^oGzM`4HKbEVlgefv7J_=Jw#-5ijzm6)@t_SG^q; zL2iT&U+e$(siF+>s9S6JgH4BQoXn?eYpgHqrR|Kh20y%v z$fhmw@mor3%l4bMl9qwYPjw5~N7-t0*PL~$SY)AHNVV7McZv+Ey5SmbvGPul>z$wm zH`};PmTP^rh$iu`FmZY4nYNc%jbt~oAdAtF-DH~w>di76xIPrJBiHGsjbYQDR1~Kr zz{p|d&Ruhw>P4;x0|bp`6jFr>T?{i9LdGx8oo=AOKk+~8TB8MB+GYGgy22YJk>XB+ zUQg2fCQ-{`8RG7zNyE{R;6n^VM8PobeW60B{T&5_;=B`rR`>@qA6|3MdWFhM2D(M( zSqrE2Uv>KFhUKcoYp7^CHd07V?uoYBJ`I;uAPTKJkU!i*xh1;flfdFUj?iX&r8FXj zK2dz3`(I>`fGR?$l9c`?NI2h3<}pnR;gKU4z007ZqCLe%d!|5}2<7(P&k7RJB&~6Y zWs34FnrGqrncQUt^mEZWaj#_x-)J9bW2?NAxW*{}%J8MV>yEvhc zDT0(W?}C3ej_v$5h|sW~j))bszq9*?_+MkWX-GCow`RkuqRD_6rb z!)54Xk$Tl$U0QEFU*dr=O*>k^m|?MEJhBd*^s1$01glOzTgnz;&Dv7lU|rR%wKuf| zzwtfz%5>bK{&s8cpqR5iQ38N=(fJt#LHX-2JT^>v&&|B zRFBj?uFcsOK()rhq4iW(zx~ZcXt#d5^{gW4nmoB_@93_zV97asoYOs24Z}bh-0L1E zo9DWH^1DU$z~Q?Cl0JWGHvif^9wM*(eM5biCCp-%S^J*;JCV|c*?yhL5jje7U zvVE&su;#(>cxd-uzJuW(OK6UeY*N8QeU&NNgU{6a`(Fd0sZ)1YWMh? z*-{-*-&$>3?@o9j>i+2+8GAHl*DG|hrcVmM1*gkRS@PZh`BD2k=mHQDfEL=I4M0}uvQ2)+Gc$9F|J)a_Q((NgxnjTwO ze4IZgrJISE2}nW0GLqTt`Qqv0)>jMn?&y*kj`ke4;8ANyNvGJ4FksvWllaZn!}%@L zZ3)v~>hZ#`giT(kLqKQzxiAm^sG^y`<8Bi%1FV6nlaL+Rdy@<=ZdZ=g_Kvujk(3gY zE<&UsnSns#X}OY{>_Hww7>PPU-Zxc--cb>1tTu>ICAQdVCi2<$DHk!WYTsDdrph)G zC=hQ$&{SF+#AKbZC=)xe?}6&s73#U0ZrKQPUQmel6tUu#b@DV-{Y4}ah>qX+P8OsJ zo@=~@`oozB?nVG_t4#<1=1*Cw7G){b3dQP>)c9(Et)CfdzeM6}N5UI*4T#7GH=7`j zLD0cXu;Xc$&y+Kk<2D%u1t?%~3vymbvhRf0fk2YLX|O!vMX7}rOrpzf=b*=$Af>Jm zD`|hD-5L^O5D_3_>Q^F=)>%!~1z&Bdx-qecfr|<#dS=pK zUC?c6Ietlv=~Nh^i7(Bh_F|Jy7-w#7jfN*Rl=P^kp%uS5T?Jaw=RAzI5N$?h(=t?H zL=xKoo9sW=ygdO;dx{8BAkq|*szWxmmEZ||^WFsG*cuS>YTO^El+5t9?uLT(%)!iP zhVC4Frr6mzumlHfr*%Uh1LoHH@{ynpM{jTH-muAW^oyw#sgG7Yu8D=qE*Tc$?^@u1*<_JkEVfRY$~7nY~5V!xVeKrVtILG&gs%b}X8&B~NtPSa< zje;8G7czhZH*MWG9PX+(-%An>_Eg@6CFXyl1O6ZXHTUQ(TajCIt$QB-;;Y7q#`ao| zBnap6(qj) zK?O!=9Ghuhmut_i&&()OX)RfJIK2Wu+0_mt;XO0(NU4t#J8s|^Z_AB5c1+RR6LiE_ zl?Bvwcjj?W$Dj-wS`9|H_6o3+z!xx3EVk2B4K=Igg zVVKtBEX{=z`-pwD3Nh10@`*vIF>&42!+)M)KiPv`6DyrTv|#bH$z;}G=uSR()vyy=2ToJsC7;*#f@qTBklwyCPbD<{uftD zKe{j#GxhsfPsYzEC!jABWNW?YbrFGug@>4_=k$dbt$IM@B#YK?arsF$QHK_Ty(I@x zY8UG#an`iXPzL^i+mZ*d#4;8Mb`&aMtyoJv zpkvUK=#_q|ZG+0|TFq3(akcmxl9qw8g{H}B zv-=Cm)MYcdXy!N*)x%opL-FXPE91FO#lzI&Yh}ARK9OU>xQRrZuJ+g|y^I(h!}d%i zFIHW2RryVME0f!)My2xLWq>SlGE^I$4VJ|z?SHCp7N?QqGLhz|wEIzqYM(N1j8%3O zf79=yM;i!E!YV};5V!dCYS-n%R;7wrsAUapI*LV+{xU;$5reLEFnhK!p`UB^K_H>; zoB9%fDP{NxNtE=Dq4N5^7q2G>2D^$<+Hx)B>^;=}WZ20B`hH++h3zqu@|aCK;|l5{ zp3+SQNnn4PLV)d!@M8)uV$~qdhB6vR^+!j@gR;V>2(MoX_t8dS6RY=h)dG;VQ>_mj zK}PD*;5rvlrh7}rlv1Q;?6OMZEiA0*iFnDqED=0zctE&5N4uy1rl?^!2BbA%X@cdq zgMJh7!>VxuA&X=Wx?Lm)z1#YG?AcO}>e@pZi^VfH%A+z1m9|&TN<*6T(wR91lU_VCIjR0)2v9QIB;(U8Yd6-r%hOZL z6J}q8)vM_Eba9Pf{wv887#r)=B@HxmC2Gt(f1shC>r{gGkxI}&_+&Jmbyh(`S9~@5 z1cSVv302-R$Xsp9!MX6#bO&RX&IJ3TidQ_%4NOHAVX=D8gr-J_U=m z1(myM%r#VL*>n`(c=iZyYU6zGheg;5bpp?$fR9vNKDF$6P5E&0S0$@=C_d3BDt!u; zYu0xB@rE%lP+7bk;qh4l--_0=A64ziaV?AF>v%}OL@`d$VJRxJS=^Y6^%l3$ntSnw zKh9yR-{G(MKU!YRBqPMcv4%ESAEkXg_4qDKspKdz|C(u?+3M)W$#Y*`S^Rd1bn>~C z#plnLp756u;`xi^-!HB&or4&by|j_`itowviFF|c$)Au!;5a*Yg;WSe+T3||NOV;0 zRkE8&+@Y0c{s;TCIv5#OV@H&9fh3BHlu}!LdOmF#Hr|HL!Nmrc%@gmj!SUZ)`9`9f z3V#`fXi>DKVQ?vMDQm_8tA0lIYOnXvj#bCS+j&E|1_e)8><^kVki9!2%i5N|E%Hbb zgqJU{GEne&9uTsnV{0QpK}RcB(In1>o8~Mt#m0J)ayAGEr8ZFtgt07?)AaG`iK%aa zjY#@t@kl{uod)B(gbAgmFrnBS3uHYKUCfxSsuPp>TDk-a%d%=b&v+k1IhkA9&z%=Ov!QEscR)Ys?bnmp&O@(g z9&}DoLsXM}XmU4~oJPA?1MW$A^l@vnP?INXmiUG`S z(&i{~3tZCmoYwEa{3H1bTi6WtWm?p7=AmP%XZsU^b0%Y*XWDm?RuuJMu&CLAD1V!l zqM*I(q_kH;F*N32sU zR-Y^SQE}!rxKSNVvXomA3lZ>FdJtA(0h46g8g^ugYMoMS@y>q*-coe@EAW=0?<=>n z)pk|U@ilMxm3d3C62Ag(Df)ijyd`zq#9Ig#DjA52Fjnf_YF?rg`A*h7Ivr<;#N4xu zJQuU!MDtLvwBM}Q{3HXU??N{4v7^tL32NpxnixyiXV#Rn)!gy&bFHc`AoyYLv8Fv*_<@D9AZ4lWFOmi-z;zaDp?wf3# zC^%HqR?sDv{p2;=Y}%%!d)Tc(W_w7tmkfMIIQv^cT0Ds0{nTk_S#3g}-hXmtplxMiJ57+knpgfGj(Xk3RX- z*BVUVgjRX7Si7>nvKO@7GpETl2~r6a5;a!fJyp(+y^??HMg9WP$lb^ags!~l^BO}X zO4L?Nhfl*YtyO)q=!+snl;hmSkV`(M)#bENh{TO?HI410T%_+t*uP*y5$E5~=IN{6 z8*UKo5(y0!$(9x`mMQ6)^ip}yN5z;Y@os+rZT$@z6RGb!x@fWIE}fB3;L+yU6HV1~ zihd>-O6uLzfY_dNhuedm)x=C3wCM2cODY-eGRO{2yrYQ@d zX!Go04&CyiV{E6DFs`*!t6{kW-nUu}XSbHj@{#IU950|`VaeQh% zEcudu3QLWR+JGoedp~=#vB*+ld+7kuOVh>&T&&!P+yL=783=n;a*Tv)qGAUsQtTPQ zntf->DhspB(u}aj=*v>FX}4C~ERE>z8TC9u!@3SI(vo{?uvA$l)TD`Obfn=55eZP5 z?%|%wSh!&*&C4cWIUI^RW4A>{630^j!d}-%+zQ+9;GL$y-*7yo1?iI)O6A_6?9q_d zF|)rSBifDVi3lx{lYK)}a}`S8gM$kWKuwh!vl$aDcQbXIxdj2DlMR z)(r%ZK>CUcFswSiag}ZY3Qki#Y8-c8WDTHtJ0s2rDVGc z2G4)Tuzt+F>p7e^xz)I7H4R{q)P(J0!?G$cCAb=QfK9Sni|Hl;&hK?e;IQP`m(;ns z*;;!y1O=ne`M%{#gaR&6a%z=RtxHWkIhF$3GUjA=t+qS(_lK&^PGObSoT;cT7vzk$c%QaDAk#QT}$f||Yj+}kL^0k(q*F*fGq|A-w z=Wp(bWApC=!yXG5zofiWPDa*xQhcS|iQPG7QM#!7t05Ws3hfI{D5;1jz7&-Ah(CJA zD$^VgOgofE84h0|{0xV{9Q`!f!fqvW1^zh#L`Q!~G3)HBl-nVCX4h)`2+5F}zy&4# zFd<3dVsrz1XDICRU!Sw^KAca|D#ewensf++#IMDexbr zp@0lzcB_KPRGM-!iAonRD{<(KQZ8Q8Y0H|O!F}{DYCe_0ku{1ixtI#O z#G*Koa}s=o0`UwHTZ7_~j*>}f)5$P5pwPU@ciw>sz?wVP{_q&d&y2|YMYjRiP)Jn@ zt}8yo%rF)O>|Ze{$AEqWM4`$OmQyNUbs!K^+Z#v{XF|qoC@_>12gF1YTX*_QU7#TQ{Oc4upmQz;!;si*D}KA z!ZK(qTbRXmp$2nX`rY@|hNI6}7&opdtdbJ-4zW)4R0%@@UaHI|dzDOKR>9g}yb)cu zy2mF%RTY%E^(a|c#wr9kw4R;*wt3*%Eoo2rcwMdEZ2e>TZG|eut+ff9dVNQvrK&7W zY^^U_&t8;mX3b?7Z?^%<1*kO|MP;+8y3xy%V)G{(UwzCU$$))bqB&K9~b0s(tVTER@(EVReffzsq!NR!oV2DsFSTUH za3F<*F+y@s#KSvVeY^%5U`=@o9o&?2OfFR&8v6~!V$9%PHw^fR*FBrTJU7mc!L+6F z6Evy#E%K9I!^K_X@xKG^J1#_3Y}P=niZPyu;jj-NyBv9zTxUOdOLjlhtqE{vZ&eC9 z#wPmm_6rcv&c1-*k6#_&s*_s+=Iwx=Fmh&KIeY5GYOOj9djjr)QtVMK8Y zOcQfVa%~|JRF95_w-(6Cd`j2WM&x#pUBMkHhSh@K zwdn?Fv#IM|FtNkkkB<8j^d0jxE0nq1d9SrZlQNxR?wloIW~3owU?;k(vpJ8--_8?!#7k`0tHW`D$vV6tE!& z5*1YnTTsl3rW|-v7o7z04z3>y!8$mbth3~G*47NU+(~~R(ASN!beu1Dd|#HpP0sCf zCOL7<67ic2%62IHWa;otZ_u}j#gy%!k_TA2RKVV(_>4WW`6bK3qBsp21(U?mQP6FwyiI)A}@xQOWr|F$g9;Z4`p+l*P+4cx?wW@!a}+dD4Gh%t1e zNDa5FmmI`Kv{oP!+noP)66-KV9HbhXI57dZv)QeY*6YDO)JG`$NcW9P=(4-FbqW;l zsvv>Ev6=tJqK$GfCCK<;iGhBR%R#`ZP?84pzF|y4?J|Dy0SCmy_JUT z!&S)T4ZWOK60bCoyO*v#aN&!*_P`lOmKU2S}gGN@YERK>4mAWzppj?22J)_!+%d2e%#Nq zRq7*tZk83M$|i9^Ty^!ltg~uLC~EL5ir-Caf40S}CU=9kN9n6%HAK1YdhOBD+n=Sj z`dg7n?-l@6IhCkSO-^E*_FCJ6cSpy4La>isf!RScx#}VoZudM-))GyX1;E>RPHmf1 zenq~I4$Bl*bB1;0yX#S1JbNW1_PkwTCXEg)`*kv+>nW6(MMCuC=540fO+Mpvu z6=d??Gy)ZvlfSpuJ7zalAPaEilU@zkI(ztaDS@dc3As>>Ryli7dnargl0&l%JhnHI zIV%si%0?gMxES!WOI0rqJ4SoF=~{UvdYUnRnNU$|rjQY5POE**Z!EPW)vnUN)r+M) zlM;GoFT|(DebvCtX9c1RxJWE~uN_S^~8em%^|s?!nGWKmLr;I$l= zv3!Dt?Gm7-3De(0gA772eMK*XmRM|xSHV+=%6^|rck5&_$p7Tt0=G{gE%v9~>a=>v zDtomKYX|NsIbf};4<1A3bV^<`_X=~bFaC@L%7&VbA1>g|=^N`)ysT=w=L5W`&S8nG zEq^kd-IjXv-QsP7keQT;HR0W1oH9jQfj}_3zTd?fIP?!L~M^?P>M3=FD)?MquRN$ zs($0$k=d^;&EysfG$buL-vee530=>ZEWe-VWD@1#h530|Mf@>;lW!bUpa{Fz#oW>z z04_=>V}_rqLO@=Bp)!=rv*$ELJk3d0$WjB_g)G82`eTe@pV38;;!?Qv^Q zIb_w>T}=Y+ZC`MsI{K8P0n)hwQp)#^+ee`?#xgwWoE$2$il^-;a=ufmjAkr4KO2jK z`(6l{daRWaFuEFbYJEuM^9L9xvsThYGn(k+c4vW8J=Qub^F6>-k9V7}sV{_DeO7aq z1Fs%${Yo&b$GRy1nM(v=zu9L2WqnF-GeERHt@W7!Tc6fRgD_c;a|+4O`2b#3G0RKA zT#pShfqu;l?Ru;S1sX8!m*)e$&YH;@Xw3bb68kz@{B46bW`q1RGo69}HLdw7YCR?nk^r_aZ&L54R%SB=6w0JFz$DcHeas4tHyd$n#sr zuW$_=&r_nQtK@)NcNT8nyR~rp7Ou)|fnCiXboNhx*PM5k>b$tK{6Mdc4*;h>RhohB z@5zlwPbei{j?Yjspl756l3f=zNy#6L!f$|bhkjkB<3b!0Ei4wEs!%)nttt+ z`Pc*3$?~(rY@I~Z>ooZbrpX6EM^w7zM5`V=VMIGs5dx33M5nvRi;IyuWZP1Ft^pc)bl+kWmm0@eH3b#36aT8 zG)a>REp1xGYXD+570`d@RqlK3+rIW~|9Zad+K!IBoOBm` zynH#~S|4F$y5{X4FK>?}p2`u~ygO>&UT>C1!Xb6_5t*q*pj{V>(5p8$ zjg_eOPNt|&P$MtnsGQu{B}JT4!JjbdDU1Y7gPVbSpw{eleFwa+n<-@Fy3Fu(nc+{n z%oKZGw5i;XI?V|BLqgWBn;>rTiw|5cdwpmU<4=)iJQ0o`jVE0$YP zj74J#nwpFT+tmHW*1O~G5TDlp-u0o%%aOr*q&nxMQT@v|>OmcYW7~1WTMZ>fT6Alr zlc}oANIQ-g-#Y4>>A8e`%6c$t`k#U7oY4WGb{5+X3v42%x~1%_&A*Qah?bF7Q0X5a@wEth(vZ5(`6p3E6v=o zW>9rj=uLTs=BJstO63Uvu!W8^(~D7^iZ0;9`k~i$A3Fa;>h@t+a0L1 z#Z|1b+<6Xt`vZU38eh^IIbW~PqLm+aFG)5J!_w4VOxbiq1GPHJKrav={i;*}ouz)@ z%Lphoi+Ac+fkUhJ%y>)h^0M2}c1Wq`+pViBdP+aP{`Ae)U+)O-GrG9S0K|}RN>xwp zFvS7c?UM_X@RNA3%C5L&E$@LoS4_UwvLW=j<@Ig?eQvJy&x1ZU-|W56=WeU+e&}=a zwLb{@+*~smF6|-E=Wb}N7InHmk7b*Cw!-=Dn<2k3Zf*>H?xrCu5KeO!R_^pB(C6kl zxpDNlxfY~6!QkKV$EHE{dPC3~0?IjBVf1q$1xSL3N8V5=!py}qMqf+=Il3{{DN4pV zMOl4Y+P^P8y6Nw28QR7(Z8Dx|ZZ@~JpF7%q=Gcu?;<(k4jCf-N(>*Ok_Ifa(I~v3{ zWeXa0&wFE1UpJ*yb8!tS`ngViAa|4;3@md*=8q#_%Tdey=Y|dwP|M#Aucm#|R+%k@ zZjMH1@rzzCjXgBC++ahf&(ii$G@|14o43$-{KNCV93TGMPD6j6|LfbmgMGe!6^4cJ zMKS?YZTBV@*cVcLO>d$LkQpb*SXPi|$n*=<`ug3gqnFl(>FzOvfSvx(8ud&M>URg{ zlMAmdj5lUWA+B`_(mTUfUHd=1`C*@l=-9XarEhaxtupiF)P9|Ay9dew7L>3gIPU!8 zZu7ix^5~mKCtvAs0t&m+ZjCVP{KGF4jYTW780a%5oI$%k?P#$sdLOXCpn6!B3~HWw zN>wCRlYTtlB-AWvEBG_5JakY$9!JxDx7nIbE?7bmukqRrXx3N*dOut5^{sI=?oK(|3rSniy?^*%}i#Es@{y#?|C0k|7Oi9Gb2zxgvD?!Lxt4v_!9kyQKVPc zcLuni@wvMYjcKm*z}l9%5`NunJNCb(0uxU*>7zd_YHfLy zCdTY}cV6z(0Wi+#!_)!!L^ft=g2>y%HEV7~|5QI=)=yW*ywJ#E2e#)Mb0|xR#{`~HTS28MKiAmWRgo7X19U85i(erldR997-GESIvQ}t>_$S%zl-AORe z!kKCl{zWIUr7oOljm#}?B@2kB++ht_>Fb?_IZgZC_L#K1^&rXhmcP}&gm*fx7^uzW zbb5zPAVdJMos5rSdx9Idv?=s4CG)Udp}ZgW-2VyZ#mz$L+Y>nShn@kzlr($V)$X@_ zAwJV056Jbn$4NTNmdC^Cs15h;4x4Rqwk9*eGv#m9KDenor*?0^;J6B4d(o?pLvohD z!bfJqs}33UL10=C9$pOxWJjHf<#0YDwb&Q+muWusttzHov>5|^2S?rQbjg0f*->NeY{M{J zbBp1*RdePLGWiY=k2pWC#R0IPvSob3D^MeDFT@+HA*Yibr;qMvV74q71gqcA`a`G% zxr6OucQke;#U__k*?Pg=zkr%_t7OE@b`|wl?U2|3{G_r@8x68&IfsWNv0-FPLmJBs zt9UiUXx&c>_}0ETVJ*75s4D!?65TYg-;Rb@L}b&|4zPhZDAFaOW8!Y_2iOcGRkh$e zI0KhWdL~)XMy%yPBxd$+_|P<=YQ` z67%ElpG}-pdC1-DArp*aTt{B$STds@hYOj4siIiao~O!DQfg1@f>dO0%?LDpnJ1zZ zPY@iIbwpWO;%e^NE4)fte969Qb^on~&Al95VSRg-;24X0XpKNnosF*Q`AqnRIf z)sTVGH8*i#yizMQ#B}<3pFGBQX>v2E)9=(W+~jweP5o|@bssGKJGJEZ9bd&epv{Dhoy1hho3LSiqdjD>Gy3=?;8o=*BhU|8J?2RVe zx9>EY%|>_9t{<~&^`$c$C&_OA&0#4IMPHf?J@bY zp6)dEpIS#}Ksy)&@YdTG~fCcOa~zZc(+h4&5l6X4@gYe4&s{WY+1S6;CyqhMMZ4xAu77q%HR&| zd*i^w*xBYjch`K#K3hMUVt${=y4x%vYat5DX7xNiA-T6@PnBJOl@lfudf5fO7$|Sj zTF!=~E*xd^So@;ees9I(yU{(DrlG!chEw@&+$K+DF$d{SiW%+pw zB{G}J6FQW1%(kY`fh#L!&a!qv>VDUV-LUbh_g*TLocWfy zAg#uaRvH!t@9d{|Tx75>pXYS;J_n*FBXUj0LcL{y{N7xtH|BCBUBah1e`S7R{$+`8 z+T@t(v_63?=?7dG`wM$6EwQZ?dp=CP)$ey>F-w}oY>XkoN9&*c_^6JAS)xoNbcY?i zqz9rUZg244EPGKsb<;payOKKOJ&PLY9mZ_>A+80gw`5*HHB3kWwB2hP92Tvt%@ddO ze0ufi_{!uTD*frA%MKeg-o5=-?5+lv-S~*r!tW2<#q4xA1OR$)f1*vMMW35&2IhhBGf7`|g-5Bz zHGbEX{a@wp$ba)#K*}w4<7-DfhgGscVYWpcB#rgnjbQ`3lggm#=~fY{v9QHdGiiW_%Ka}QnkGCMMlr{gpq3GV*{)8jaP1f zC7W+k1fRI|O}jnH+;NSETo(=py|(K#IxqdsnzK883H0yzu#(m0GG%gr1mBE$=RKvc zmxh8=<_fs9md;e(BUtTSmvEW3x;$Uk{+iQAG#&9X(THF0p|U;x%gg<*k}9d*+->&K z*qUB(wMzcoC^Qb*4KyMlZ*CUtA^TEyB3wi-n7}*j{XDYRWwT3X4$h@?s|Fc_F}Hz;$NiTtrWOrl4sQ%>ZtgE z1mLtv{X1Has!ET23=B0HTxX;de9cS(XWPhM!a7jBEDK<}t0XJp3+qeblkVl!vFb$R zXXx;S`V7#%?sO4UvE&piLjEm&**~73Y|*~_qAhaevh^O`e09+!1Tc8$n3cls4%K~u zBg|^6^^w~z(jusjSdhe#cgI)wm0?(D{1m^ruuhS+`EbpWnY>a7yVRB%h+e4Wmtvqo<7+MyFUQDAT|yw0$VhAB zZ&`IB2dq8xZ6#AeYr^WBP8Gm~+?TsCMU5@yD%Pdh_#T>p z5w_^_V7L3}qBR{)aMjC~uI6|b>aKL!?k84K<{mS6Ls_qw6bP7d{2e%1RmS)hCJ&KW6FpN`33e{o{*0I0c!s|MMg%v>5*Rm?D#!rM zc8>lzJew#tRycR5E>US0y9O01^V0`7whr_?>ghKAi8~BU_xe&weWcr4)9_ZPTm9-2 z^{_Xlwbs78gygp$F7+Y)mUEP^JsV&4WpMJl4guZ1N{iEhd)v`!VvRA<+G}eathz#y zfUw}4uMSqZEdjAWM6&$iE?R?g$x{bhh55imu47!Duqd94)F5hu2j~I`d2EZ%y$cZjFCw z_`R@?is~ivg#T6{TCRV1WRZZG-cRCz!ZbL!vRp-b=6tj9_V!)&8W)Y+vtmVfz*>%7=x*R!7dMzjM)-J+ zd%CiY`%D-05s}ljha}zmP(rl`4{vzsnWxiU-(0>W0V9q(?UsJ>XJ}g{ttAVeu`8Sy z*W9C;dgSn-ph)0X;U4KvXaG@9&XewIYqS+1QonG=3Xf3sxfPWSwd5Dl&DLq}xH297 z7#T$iGLl%C#MAFE$#J3ZQhvjTsolooz3*P$;l8qH->v}}?)UD3;9ra8#cJ1=&*_K5{r6}3kh+F#G`TnvCEK?4$mO*M+*SJj)9kIch4 znL_dox`R2U7!i(APz9s8ed*JQ^r|!=JzZHK(RP85u~fN(oq?op3}ck#_o8tkGD^K{{*$@rtaX_;^FHU>w~*npi{9>77B>r> zJ%u*=GJ@jP<|Y%#ld;XBX_4WYyDWEFd)IxY4v_;fpD5D7o|L{*`4rhei*WCAEve4G z!&ool{`SM&wp1QY80F{czMFY`W_eO5NQJ00*NS5;-E#=Jop9rsYb6yxdj8oCi@UCU zaG<#c^!%QK_~5Rr2~26xaz~LAUU45HPOUAQvDDO^C+s}OajeRR?2WWfHN$=!J}4jZ zUf!J##rtV9#i9j|9d~_5>DRjwNHkK=Uaf(9P~QbivvZ8c-G~@5Gc6~vlG}dS7^|Pm zdTIWAsA*as@5S9lHGxrt*F*j|zP>yi_6-@!&Zmk7)|S3LA?#Y7AY`>4Dgrh8#f+DQs^egcg^#k!38jN&??u>fdK*J z(-ZJ8x7|K|bpG?B9n=0E`J0dKASXZEmGnd1LYpVcW#^ySDzEqd*%o_!3bINd&~K>a z@cX@Q?pcjHzEF`qSl!gSp1hxW1kk1TNgwW0)wrX3BZhal|NQyeJ5~iOi(T`-w7)Z# zmYKLy07JgAT7Nk%u}meM{q@V&&s}Lx)*HX6^Q#Q^(nw6+HW!99#I$b9@EP0(%%h<% zCX<|%wnvmQju_`pq?w8zfTB-kI79&ZC zq3bv0JvqS7foELcAthoiF+MB9n(MWg1Uvxtk|5AVzR$E$75Imk;~gf>m*=(qgn(*u z!kP@*gt%fuZ7pW8gT2#N>`F0Iv#M(SnGbtVl%H~_JNHUPCZ09 z8wA%M)rMU<;$Hp56f>=TE{wP(lu6z)E*gIx10{0hjQtL62dmi3BaV-AKnHZ&ow~UG zoIX^V@Y_uov|I+X7fH&?$Hn#l2_i)gVIL2x+pZ}6PQ%uYE377FyOLvBG6y_d%UA() zM6l`hjKQZ(l$B?uZ&Qi1WBQ*Hn18#bm5t}`iz}pn@!=Og>8J;#>EK1P^^?_?S>;D z`}IdK(h(w+YzoYw4bNQ(nvGZ8)+m@Q>sGS&GcE+W*OsXM$!ULh{=}&U2-q?2v@f1~ z`}H?}dh+!*Pt1>kf$fGRb=T)$SMBh)Db9Z;P^y-pt%+m^6H%ebUsiccN>jNBa6mbG?Qx?VKt(G95YJGL|dm zh5Ro(nLF4f?Jy2e-#$N9@5~Ry&{m@6I|$f+7iT*n&W^`jcB%&;*omyGB0J3e>H!0L zzuyCI2OE1_&#{RRP>>k7A3$+KPP#C-Gz-njxCC0U)sFa;kza0P@m5Phcu9~Q_ril& zqq*3}2ZewlvB%J6)?yPrinXz0R_LnN868bnH2S)B{}ONq3;b$DoS9qu7yWvNqv`J( zedgAg5=6|GjY)Is5Z6YkS+&NXvK#PgZmmhI(cC|sWg4fn?{R9U%~9bAtbl5BW2=sJ zliX0{N$JHoMLW6<HTLMAKla31#%ouopVt0i4?B?wu`j;5t>IE90mqM`3_IOw$v zo(+VJy_dW->B~lOG-^rD=0=($hgdSAK=5L~PLy{A{)dApM#iU& zM&q9vKYjo5=(&CR%MZ_=AK0h8*WW$=!9M-)e4mC^w#g)g_838PtwYr2DZR~7X7M-F zD6}FSxxQ=RVfAc+E$A_kq3g4Ln^k`sk0o%P;#7> z9!>fdJj42guDrzJMi`C)GS&@8MOctO2;fjNJT#PG6IPh}Upglka${t^u0m z$aErb&k}gYVR!PQu*05zGPepC)&H7yN7wO8<{^ebK(jXYaL~zaU^p(z=#GC5Tst`eRF{rcU@gS{XAw+}Gy zur*h-oK#((ZgF_ceGkR@SBt}Y<1v-!+OZr$Q97JJN`moCzq-*=bd+|7!k)P^F;AoQ z_oPAsV0e3{r-Go&k<-~mrQh#HnDm8;zvq3d19&y5A=4mXYW%jI@|cEC1}zJ%$tJ+k z?C0SPYFGQujxBny{+y&Y4+?F>pDlqmzHwd0n0v@*a4cXH`39KkAOq6gk58WO{}9mt z$$LW~NaOJt7EatE3|JWcfDOg53H+9e#RoK2tFqe3k`zp}Uf}52$_*Q6u2>~wH-P+=^ziNcM;qnH2M z__q1=B8kMM5kXQ8hL^+Xc-Ny+ObW??_!3yM0o#7+fMD4h?ArONU%Pzm?+OUfewIDL zKJ>0W{Hc1(w?9|kE?e#53!y%r>=ly;Jyn28h>DU$j|Qrf6Dg`fzz`-^QIRm;6+nnvXty{MclV5?Is* zUl3!_%K^p;E(_%SDv4Pj#e&>4LBfOu7ncW}Cs3n}+hf{b3+?pZxoY zF@ux;a{{X6^P?AyA6`6beEZ)>x8+?Z3t$^HKT|L(7V`>2x2D5Y`*QqHu$^cR7Eyg}3+MS* zac84en1YY42IuK&y{XS%*v-E7*V(A$&LhN9q7oDyY??o};2X*O;iTAbli?ME)!Ll= z!K}2JcJc-W04nPr)vk5+T7Psoh6V#%lRmLwSV3-0-Toc{X4gPQ>;A#^w`~O60JH0Z z2ce4no}?P-JLXKrF$2O2AxZEZAbxUAz{SN2bQJ(oi=AS)^;h1Fn?8na8GK}IItxMUEu%|kN>o*l`4hhtvfGFCR^E;j z-%?Af|I?rTsBW(&h=`ovmU$Q+hwJ8n)#WUdH!J7IQbv!GHo$7tN3u)#dHArZ!MK2oIxDdOF1Q%V{(@6`ZTsJ zV$*T7^+5&W@e(J|OzlzdNdwhz;t;Q%r@# z@6n~k=fv)k?OlR zL!7eCrLUo26ePAXfcurenZyu|KV~QfBB>w1?@#USl{>dw$XCd80Z&RI3a^ML=oCDL zm%8EC0gaCm%TsUBE-#U#Y=clm{2sC38RTC-+reTjN-<;^Ic_Ra(-a4JR|4VO0HA~6 zM{BI=Ym9wnQ&^Fz!eZ)NxAcAmtfG99eWiY|) zS?zcL5J4^zF?){>_YPp?2eJ^!#4*mm9i^)7X{!|BB7;=NI?R>fG`1vjc<9(hJ&% ziR7Uwj={qkW9aQ`6(s9Q}7b*e^~ zABmz_-&bGVb%W=;9sw&Xt`Yl%A@Mx!TXeasG_1A)v{Mfa91QtxILIkK%T$S6!g?ni&Xw%Z3 z!H`h^2g0W#C$8r8W86!vo_0ArWEZ@(S$90TXOk|`9>ZmiTYd8A;VG;f@_YF+T-u;< zibQT${#``ot@W8i(IPI5c3*J>%lFULngzRH;=GaXBhqsq3bV0;7oY@OxRnfcoyHq9uaJQa=axI*~Ro!hxC*4VV~0c zk@xK>f4^zsZ#y2fpBQ-8@QLWb{%M{M|M2RMfBbK|um1SYW+qurEJ6xb`0?$M0h~NU zgY*g{b=S6TlLGEs^}14kw(894h9t-akL$0y4KW}3)#;cY-CYhyGhZIVOjSDY%Ews{ zNblTvO3PZ;JoE3}_UAv|BgUZ0Px51huc18`JZS|+N>Ncvm-H5-7RqBK&t~QC58JICh1M#9`_->-!pga*cehOa3^HlDYnUmY!Lvn#_J( z=N5EdbgG)IlrWX~P?9>aT+QmbGeL!1>dwu?u|I#PR^zt3Hcop=leYSd2FbDw3Z$g0 zG%{VAaxnUs<6N{~&k;OyIg&gb7xHE0=OoaaO-D4%367L4!Rlwo zmh&tUL3jk=M9u|XQ>JELQ5ScUrsZvo`VUd88f0-rZrn!E#`q9W-qrv+ULjJamJAL&|8^q zKzCF&*)xv&zV!o7GO+Jtr%XN*zHqvVv)CAVfYd51SgGEwgT@^eVdxGHtly+9ArJg? zA-@Ef3w6sv6b^Ac+~TnU1G~s;HD13w`r&zF@960NdiF2>_5Vd$+uY?POuz?eo9hT# zsy5WGe`rfl=6y^$O=I2cV^H3&e_ZPAjjL5Ub86A5@47$yV#Ybs?Ii=we5=_SH^bRh zSHV4ueM#NGIIg6+zN5tuE03UH5Yn_3JWdrn-aEwf!#<-@*aO7pg0 zVDOX4H|C_^9$g18xkE>z=2!VZspIy6&f8xffPK^;n3@IRc(od3cq)!i-EkX$W_qag zOoyx3G)v4d6S|ckB@UScSy5gce31SB2Pg-f zO{SpDJ+0F3%p$uo;~PjjduuZrg@(SpHK`ROx5Su5rp55~E+Y%bBNZ|6GrFO@Rhe@T zlDOkD0|AaA4yvgIfasHJ!1Il`Ze>fdj4#1`O2P;g_1^|+8Z^g#V4g^y}aQLxLi^)iQsT?52 zo*rnNKWhGr_4)3$w-(HY6;CV*Im?j|B~?j~H9y6f>q)z#ftyvcFaAKbF7+;X#_IU6 zDYmwqn#AE3s@=0qoUkolfNPYtel>8^|rIFn4&iE zQSSDM(sXUI(j`Z?DtbwTUzUY-lWAC2AD}cB9JKzfsaIF;?IzN#uHIT)2_T{!aW zQ`c$ZLDHnI)q#o@aGAeLhSp_h|9nDNyg&wwcM7Pw!HL^c|ZEo8j^XZ?F`v z)Fk%|SiA0<-gKp=5_i0bJfqASCuK@j>T>!E-H_OojzWAq!Rc*jOc!)MM;8?s1r`8T zT7uS2U3x=9_f1!NW7VVKRKOpJi2VA)C@T&slRGG}l6^4;WHoiZ@z$G}ilcC*KONPx&q?_ez$2rYqK(Yjr5TBJGGW1BC~WHweZEJ^1PX< zeuo!vwT1oiF5x~?n$9}m7>?t@^ET(aBwF;hkeahLa=(*8)Yu0<3ojkJ4dxzJ^2W;P zIO}!hw3}3$KO=g|c`(T_v=NR^1nTDKh%!Otol*=3sWTVU9ti>;E?wsGHt&%lb9tq4 zi@CpkTFm8j>K^)jsW6w6lODKJq7<*+(f`8ryUaH+R!;xh2f?ITf(DS#^H7cemNhXL=r-V6IXq(9 z@m$R*?_(5Mx5KH0h!OG?5E>pYuWf(#RjzObuDDHD!Nff?wEmUV88) zrh}{v?w%$Pq0W=~0(nk%JxtaZX(Trs`ll2=zv>A2+eRns^we0}xQjkVV|nXa)` z^)^N08eUUz3;kM`(ZzkX&@I+T%UEB5<+iMFpf{Lo+BQdfosOtr+=f@F7;80#m~^0! z#My3cApK&ktqojb$BpX?A)wl4LJyMJ2_z2Sm8X`9H$96;wudu9Z8WuFZN45jo#K3J zv%zRNk6ih;Z#6yWeY-`H=>~KAdg%yf#}nf6oFM2A{)WW z3L0bysKb5I0v64A*7OuqX4@jyM{`&|)^4{;zDX%ucsW z`L|}uzhx8Y=^J#P_sk>t<&HdPC@Yz6+#+R#EXIh$Z--Y?$D(qy5x<~Y^nzU=hmJ2! zOg$h@z2MePh?N9YM8)a1K)imeOooU5w$sqx=l}Y4?_i&=mRAYil(SP_w9Y{_N&deN|PTGd*9?suJ+BxwMxb zE+t>pUeMf;^ifWd{DY8)a(n}B0f3rp)9`&9-!%!JdPNSJ`=;2N zr6J4OgN^eGN~dfS@@Qu z$(yYRA$*$}PpRg0K%6{KYP{JgcXeu;4)5=t4sUi@K647ZTH`tSn~N$S<%bkmh(AjjyJcTeKL$x`}G;l8E4bJcC&AP$}mYwDb^Z=4#CpdCaQpZ1+zs zx4f0VM>@IXy-|?kgQk#M-gLNDN%^slaoe~~+PGTfbwJ-p+Tf2<>IGwZ8EU_TpZ>L_ zimQ+A_mCd0KIToQgj-twZ71qV2Wm<(w(f~4OJYfhQ4hJ5Zb<#MWGMLnz4w`#MpGVd zw;ihKowcT`Y+%jv^G@x3o})5+o$r{wZ9F`id?a&Ib3vk{^qWO3c+wCxY!tlQsNN_t0a{U$ghqp=GAo`*{jphw|6>r@ejq z@|S0C?eDAJVEV~EUAEe9{FQ^q+ozY_oSg|z&lk*G*Dl}c}Ve%DTUmOC=j&D+M9uErUjeS~UqMZ$01;GQli#=I29wzLWU zSgU?SN)aC3ee4>;k|BFWzBwl5dHNO%wb}UJH)WXf>UJ#AO}Y`(-C#2(t_Aw1)qdZ+ z>`maE94t@#mGP6Ky|2Ii`r9XsC26*!qsE(NeLK<$d5J|7_u!qrxz82pIX9}l>#kB9 z=~p=2DLvyHX`~>l~4OEm?ZpFnb?2aN{ z!K>Zahw8^i^sLePK#s)LDd`OtO_`^9ef~*45N|ADy-6d2@r`VgDX(Qf6r+&!H6W#m zn_tpgU80Y_7|6mx0uh?S%>*)Ao0Cac!HVn`0!PxaSZN%o{O9G6ayt6qvMI&_9gBcZjLv(V6KyB|qMn^tGCrWP^w*NMPI|DUGRJ^r z)NT!gOO3ZX)y$=miK-dp{OpDDYeg23KuphCOy(c{;SYcKgF*Dzr#~o%D?Cc0?sfZ} z@jt*DU+5DJdY08In=C{e3xxfLUv_tQ^Zyk7p9qGaLXl$Y@#!a_hI{x)Mxg<8!P496c z`g=9vSy1sO@|91-qbd5l`eGDzk9vbb-+Dj%AiPI)SH@;iZ7=u5R5Qd^i`6G$Q-nJ| zH@1~nODja4-ZKkgaUU@}Sf77_e*4|07BTZ3Ws;L1G>tYk zNbFhv!Hiknq?J*QBoOl0Eryc^eTu<}NmQXW=PbBl;*DVaUFRDw;WI7a=bag@l6q8> z@t#HlbXXDgR;1M*4=vm1$6@tQSw&kGv7==6qbX8JoLcG-#;gmY)!9pLA5(&y_=WV* zBRLZ%fhLAL`;Ow0j)^_$wl16cj9A9{>hf!W}@6*_Tpqc?uRk`Z(Ohl~vx)iWQ$_aPn@q zP;?}!G&?hsvb1)UW-1T#CkQfERwv>4KCT_ozO0Jq#!b=e^;ho@$X>4^T78EA@cWKo zuTRXEAHH56kz5GZid$px9t)g`5TW{@3zOyioHI6c9=5~+F|69lw?ih zQx2$M6EElLl@r$pYZ`z~YY2g+P>FoJ%bbXRVE<`d4pO_Z8i<#kMr*RTu>n?JDG!s2iaMy0+Mc`$1JIm(-EtJ%Q zWGILM0AtnfULq7?d177W=_mDuACE#OQQQ-hcQ%}kjFz8yhkHLeC75P3_5}0cFA#GA ztSGm{jXvX)3TTs}&5+x;=%Jd7+82an*C(So_C1pA(P{6TRJZN-?3hRDPEk=$ap5n} zL*u#zn`*Dm2(^D%(OT6{V=7M?*QVWBb|hO0sVLmK>NWOX6f;uzfCFJDX})nqj{V`d zYYG_eKQXp)Jpb5(C9#6TkLm~(yEJQQ+L?m! z5LqUAZuuF`WFcarv$-xBvk6+b+7htX*Z}}Racuz;yIduq_twCU#AOkJs|U@-VQxFp zLD(?8uvH*toDv1&6o9IRFsuy1txJ}2I-HLC*E>x3d27@mGnLs9qZHwGgYzlHWn1_- z92qK~Ge(gvML7{H{Z&&C-LdK})zM-8)Amaj%FodqCXq040lmwif#vzdyWUKBMkE_z z#_*~TwHK@KQfpn`r5aOgwTx1_2p$|sW4YF@sWe^NQ<;R^hX*eTQ|}9_fo&ETVDSi| z3XMOyW`i^}dx4oCYw)&uFd>Ly$hk7^O{TWUY*;1<)oFqbl+}E+JJB7w()>9l!o)Zc z#~P|eo3VxkM{A8aqHV|w)-ilQTG#wM`Pk(+wOI%oLl`9NaAondI?g<_Xf__RV%RG- zl`+GyA6cv3BsNK{2c*aBO_=uTRkQ@Yr|IV#*%A732ByF7yWOh>StRY4uve@vLC!X1 zrdwLKW+zGP*=?N+dZ%2a>J)SZwZPEym5|ov3g1DYiNsSg$}p>CM;hj=IA*Q<46&m_ zJJGZ?xBwP(4bt9G5UY+wPXwo*I44IVe&(Y=SeSXqdXN|sQ{m^*b#N@JoVD;?;MYUb zB2XP=Od)2R;U)X9!%Cb^vE*aO%L0}v(+TA?P^hs!&6-R6gQnP2BvI<}ODs+`UBezb zLr8%#epIBXS|oe=WQKY3djT^(hDTnsu9Q9IoG$R>3=->(xB(eVz7lg7wLbDpW;}Wc z;hJfOkDV@rgXYa9x5;#Q%sBoco>^K`kXWn&mjrCk-m`^gtNMchT+HSu8wicq^O^$% zVkWXUE!%945%yC}1rv)55tPs3rJWeuA`dRh9Q?399KPrJPcD-WT&}p`W{I} z%XD86=mKqkHD5~xQrjmD*}TRLy^l4-1*p38{qaIFvP{rWcPW5sEo|j9$##sfa){zX zw(DtE^IS=yu4t$nw3cu4f{JH^s&MV0EzNUmrNRvraiz=7w^yBGaO{J8(~d`efVhY{ zTS<+N`%oGe$UcmOGfFdJU5mOaE{hzE^k4>bKwU05a&Tx=8rNcbjJg^cgtk*W3=XMr zkB0E@-o)OvO>oieb27l-0F0C&l08H}{65QeA`DQI$R=e0S`uP7_;lln(8>73j^T=n z1?*sdvzDlMX!B|wY$lr&qeGa5;t1w7XXmk%QOh$6tTS9jnP> zNv4f?q+H7gZ4jqk93Oj_5+NaRQVxw1CkC(aB$;J{vTSdQLuc{J%Pk%}1gP_56FW=C z#+n-|T4xASgQOd=N^G)neQm6)XryRyp`GNn5>RzDcE-J}*j>JmfmdlW*?qE6HCxYI zs+k$6gBiz97M`E?WSN}RnSa8gg4GYkp?QkIhk}W~Q;77wbR6p}QEYONeY%DzNW9vw zv4Uy*@Y^=Zw1ZvS{_i0qRpUUamVsQ8h!8WQ?=3E+=$gB{M_JYE1(zhQ?C5%qx9dl~yB^k~PC4Sy%N-ayV!T zC-$W&7XMUCk%L`Ch$}~w()+Gv(x^k6ydbP+6L2dCG}9-T$!e9HK?NHbe!&c3W^+qi;_1~GLs*GyF_r2p0xj23lNdZrk69GM?_<7ulOX1!4FvV}-TjWW>1^UYWV zt$(ICm2*=%$t?YekbZ>}>OC;z*Bf>6o>B|6m5bN}o=!-hl7VR5+S(0O60 zW-*@Fbu>;2aqc~Py3^QyYJHit5Y)TDmAy5Mw12d)6Fk1L57FY&#$Wd>5AR>U$6Sie z_5R0UACCMj+cnZ=+Unn`W-(+tFq?0IDi^& zZkB6iyuPZav_tz|B0}b6e}LA#<38peZ4mbv@@-@NU<+~VtC&dKS0^p4h+X2LOkJkA zaUzA$+O%5DuUTi$4CHE{>%+0kre1eh4d#t~R^K*;#4p?_8_)K4e|YnH=FyVn;lP6f z=}3PbpOVp5vKjO)`o+ZO2|4YsJsYA0jGQmR%TNp3@2!|=yXTS+G((-?)EuR7e#?8n zYdKCZ$uG<=?3+Jh>XXtHt=(GlLh_EPO;wg}9*TNn?V2ap%`Ll8?lD(piiaeZ;yG?D z5**mLZn8t_Nsc}9rHox;)zwT4yuAFWm)G0msLdEAM=ZZIcg_V`MYI*munCe{bKM$A zyNV7e8gPYvbDt`Kn|?{CPk~t2WqW6m8LMB_<5lY8*aAacl=C(|#Vk}^Ly(xX?Y4Kd zDTpeY_8Q|Y(yc-pP9#}E(zcnM32)BcTd%!5mk%+RTzNBW)61tz1y(1RG+VO`G)YqD zndX+a<3-fc!mTt%&CU6y!o|=@V1D7}eE@Hu{Q27Bgj_xX6jCN?FZBgIBp2|sIUG@Tvkp|QqBk6&T-bv^0X#1K8yM$ z`ReLNn6e8m;^!SySJ??=3zXM^U+$Xlr`{Dl8FTeE@0!$cK}~l`=r~^wgAhBO9j-lu zqGW-Ppglj*Wn`abFa;RQ)@vkrzk1h7ST{f1Ko+0vmOZ>*w;m?hQtm(U4Qh{=`P+VL zB3j(dR}INN!62q#yAMW(i#O zg6{8AiPA1B>zNK;6>=-l*zb$wkN;lG#NV>&w3(1ZXg;0!1PJ39G?kdcsb(3(lekm; zgq5`_=10D%ci{hXagIedCa~G~9za0dU1QW6>~=q0wD1t)c8EJK21LbSK`{fFuBHLp z!640;O`k!uw;6wmCW#O82Xrf$Z%3H4yB%GLUNAbq-L4ZBtZg;Z zvISygZTZ~|S4QW$F*?ZR?Y2F#3zAG3vR*@c*kK`q>6NYT$)#E|S1T!t+#$%IbYgut z@she$HV-~#9~Dy7nJGyxGHE24#Gc^Qm}{bLkb+jUlBxN5k_s(R0Vp4YpJ0nkFRX2RG_E`DP^x8iS=RnhbQz2jxxNQQ9JhJD*D3BXa+Rp#-)%fKN}ZcS z6K!u!ylnlma<}DKo+){2TIHG2w`Nhc(i_QoY&C6@9Gf~X?lngfA-}zr7+27b&Zt## z8vFb%=k}RjYpX3vVQdu`_0C?s>v^ySZDwuUyhAIm2|dpIbK&^bm-p()VuRbYCEY*@~70$ZE31kX`aY zBGeaGe3oJu)M{RE;CPAJ5$O;AuE+)6h0?pVrexo3Dps9=3*6J2rlEqp6Sns^$naRL zIF^0ZU4xC^>!+|)uy_WCm$>pv>Tq8f4Me3qILzTfYVJFgdcmTje6&;0b9xtje9xV} zDpe{PhiU-4`|hRg7rkZ8fj8jjc=J`JS6u~E=V-vtO5$2>E?mcktAApGzfT|IOts&o z!sSpPiAWaG;C`b_!by5xunm`&a<0Hxayr6UFsNMxFq|%oeYO@#da=SX2Jdl&l)A&@ zxi!VYyr+X6p>;bF6X(np@{3@t4PYWd2D*a}J)C{zJ(Q!Po|?XAzRT!=Q-zgiX-_O1 zU6Wz{yrul<9TgVC_ZkivZv(qUE+oI`yDT?WilL@rulJsn<&Kyy2I59k8MaXG%?a>_ z7tb31?dv~%D{2}~&)voQY2&&4^N?%_?tUD~`cC8j-aW<9RCgO+sd&ELz*?XHEuswm zJu9yNhikY`tqvYK7_JdM&*i>>S8$S2-D4TCj(0wvyXcP!`*ZNhye`ASU1kKE*Ef&=Uj1xmEyQ zU-wjgs(V20z3I5^k@cwJ3P z*$FX9Sd65iu{!uwUX0{6X(VtKK87uJjV@FBxDocwaK#_RJhovzOsWR;f z3;yt>Syo>V`CM(@&*VNY{=ejkCk;3mZWnbe|K{_m_>Lj_VR{O{!1VUH4C(Hj5fuCz z`qQK2k|dg9LlaF3W{;7`94WyQz<2S8PL1VsG$e3M+#hq9pn7cGEnx6XE=6-5s3YDJ z*5<<0rtrqc^2auV+gDGOetG(7N9TqOj;)`EmR;2#F}%A`B_>ApedGOr&;ghlqt}Tdrf87t-UN}O=19rOO87s@ zKYWz~!D3OC5l5n>1=N;)T7}GF{f@%>$(iU2sQp=gIPD}CoRQ4BOhkl5Xqn;&c9Gs< zT}~$7HZQxK-t?054)?zgm*G!6BdP>v?v4~{RRqZLc}TsE5|?7SZ##fztvc5EDSEsa z;PI3tp2zLc`b9WXtdU&mt~9Cn4l~7gVqK*Zavu(NIUA;jiTZ^FR9VDes${&&@t|fC zE>+`0uL~3Mcnqsi4|GVV1vWi6)%bGYLP$J=kpQ03qKTw+rh2_uYPXq*YpPfT`cgS) zu!We-OW4ZA6sd`{s@yHe|AiZ!H=`U1{7=3;TUMNGFqbb~2d%o6O?+$rh7Olp9}oTOjQ^vZ?k1+nL8%nhZvqTX8mZ|cyx|CtOd^KI*}$7(PC0I(@j)jEAQdPYe8{T zFT`5I84^>YVkl!g9TRci1E|0kF+3gfL6(L!%g8p%Z)$aGd6^0K96Dm%3kwY##D_~6 z!h_-*nvx?xCS6Y1 ztn(NbG>;NFLS?4ETg45&d-rmGN3Qd@TjI=Y0(9dqJVXtLq!HQJm$+E>1}Nh0msb@OpNv3r=6b;wZp(7PgFb1dYNGA?0lD>L{HRjA?X@ zqYh@r(Td2b>DBGZO4#}`Ru;Q2E4^Ld-_+Kv5Q@=7PsfBM!A9%~8MYxMA+ZVf?UcP@ znV4o*fm=548)Wcd>xkr=sg40x;{+dOI8 zJZUr6ghmtYvbu@e@7e0^>t4K|woUpNFRDIv=|OR1`RrhpEw5LLcNhE0rf^U*8CVr= ztbB;9dfvm*g|xWPN~UA)19nooJ6$=0+*%V7p&nts)*Nl~q#32mP><(H>-SCp?Z4ip zN|R%Ag-p(h(me1L!H1%reGHhRZSJo(OipJ`J;ND&c5YmiOa4$dX?FEj z@1Wk*tB8Z}-S1w%xtcDUj{CSvEvfT2?PauN%)e$Yqts>6n1RaDJqG+mw+8aJeii6P z@e|T>{6wNMTy4?^~!wFaHW|mD&JE>Nhd1r0%TS6KKa;ybB_NqE;i}P9N*t3 zI0v;sUcw>gG%}dr?0DJ*5gz!l9Gxg9o$UOp>iwO$mJ=AwzYwZ2*ze;me9`+G*iz;> zMEBpmeYHQmw9tuCeXr(2C_oR5s#|OA?*yt_>&55B)U7oSNyxp?eJbBR7^H5kRfMy7>T@pMy<`-ILN<22s=q%&EJCPnh-7yKwJj;G=xIS9yX1rhua-qapX z6EO`3IM1sLMgp80E$Bd%=a4F|K6%&*{8mrozfMns{XzY?&++^n$o_y=GAX0r3_iiF5|xPd^~DpP|$dWaG9DgBG@- z%S@tvMwH*#R4(W0a{(i~xU-T>j}704Fer~ayS=|A&dRJ(0Rws5O#zl^tXdwQIkC&Z z(Tl^z>la54HoBU#??wWZG;6hbzu2IGMPvD$1`I5kiu+2xH8T0~0tFUK%5PqLuPxfI zU3AyIO7mtQK&_$`yA21hEO;vnU|IN96hIXYlgB}Ee-;-V!T+liPM69u89uf4nilurDv#nY^aG6@6C=-dk`<@#%8bU?7c25{qjm-ZUuf-dQ|Vh>iAVrH>Mo&SZ^Mt zEvh#eBgM!U{ZEgI$y>YYTadP=Po8}I__3*UKo17e77Ll8#BrHe!Vkz@km&;DudqoH`Xcv;90sIh3maHO< zJ)D@+n3&^BQj1loEAlPlTm+Eyzo|eZIGCsWiZ79DFXx5vk{(s+yn~#4CgPW2?;+Yp zVPL2b_b(NAo1>P{ZRT>b17-0%#daxx>%=bqcR}Y+!h7gJL1eoY(c860;x4 zM-*|)iR)020V*b?NL_!8*$0d>fVqj8J(+EOCWDn$?h%R8BMN%_NREj`MTXe&0vlB% zmI3c0=c8gpYgIpusXS?1Th9v;R#Y#860pOtvVSRx-2$L(LPBRHUZ4+v3IT5R4m*Tb zq9t7(mU)OVoPmg~s5j67(gerRnyZ5#HlOV(8nX#nxY|Ob?biM z2aFT(2?70ysoWXh+TJ!pfIBkC>DREtSVqJp&`qF6Hk~B|Oi9@5Yc3Eg>?RBpiv!N8#YuEV!#=N@MB9UhiK5 znBY~}HEfdY6?f6_8IEnsD0>!Q%`(?|5P_cFn!Sp_hGj_8&$rfTuP?L^HtYLtmrTc3 zj*Dci`I?4Dr>0C8>ORf0lO*=+q|Kmr%2k?0hBC8`B3gx`;`FAVUa}=YZ>6{$PYuin zMo@O7k@8~38Dd9=ShBc`XkOqz;(a1>!KydUn<+yBKLOl68u2q9E$OTgv-N=aGsdK& z7n8rR*c>9#Drc#^7s%S|Wf7J@@tH#WbA*_My$yl~Oh|xKSxiu6hB*=2##%BNCZ`m{ z5H-byriTJ%QerUG1dfH!jsbB+KYQ)JGx%7l?df?qKp4i5z}2Mb~G(oPKSQD%MzaSYs? z3vt34!%BRCb8FZ(97!Tnd|fU5cfC>{O%gJSdUGPr5Rt6Ag-@4`Gx0%EKv*X8G%xI` zxIu!AIqn$2=U@R&4d(=}GR+DW{{f_{`7C%-Y_9eNu$bg9I0v0Z5$65j@IA0=O|FZv^NU^5K6DoW zD>;^Fuz^wl&2*TLF=5b6E`4v|fYboPAuq1yQSswr?+O4{ zV}{C9e&WR7HIhKyCtouMw34-J3_dNXms>pel%{(FJ4?sLnj0%xX9!Y*u3`MF5{Fy4 zzBX1?G{DeYXm?s+Rmru~>h+ZzF-uzTD!VZ^fLXup5w%IikOaq!b7cxg&wFw%UkaR^ z_2fu|)epv@c|rh5!L-vL-=Fyw;8+*NuJ=}ioBV4F60i1atY8|yATrt^R&#vOvz~!X zrEvga+#e4`!eXfmBArGOhm2;R%`5XX@D4oAL-6nRQVT;ZoJ=RT<-cvC}lu8jH z#?UCG_x-4+Pib@I+}GyaktQ9$;CWDBtA?b9h8QL^y2F`tO8#@>xlNT(r}LVGiwlyB z1SUG6Rhm_}UhzYvvq*1~YN>L;YD7pO>PoUq!n{gU{6wYCCQ3}|l;{(wX;(SxUx>Vp zYD3bl$>gd7ZP6(sRaEW(P&Wnz0kdOW$&crc9W!^Q@wzAE7~0#7q3nX}Ng~0?_3qwO zvdZ9m4(ZpYD5te&2Czh36a6dNpK4l0>Y*$-V z8~rDE1>@wL(s@8b)`$S>T7YSuPl0c%YuI`(OH?o?X}A`xB$Gi)aMP*um*Fv#Ms%IiE7VEz*R{OlCF5v2FZ>meKnoTyF=%hVZe0S)D7H z`9M&Wf&D5kd+N=OWC{~|gef}&TaZJstt82+Yx%G=-SvSjpdeFFH*nI!N=E?LGCdN4 zt#5_#Z;=&IEzejG!JC3t8#c6?xE{e4b{$ml5j6_j+cYIN)!A0ar%wzu8SWC`w9_pN zdmu&9JVT&6?ZhA^l0nj2rRMa$12+ijGQLb4t76=7>VN2sg#-Vybu84ohqVe?|IB_c zX9|~1c_V(usiK-k2HfPpl&;b;Z>x#Pu<%c|3AiDvbnPy9BmN^xy4*ww_+6shE}f72 zcwa25^f&Fjux!w<5VI!z8o_O?&kwfEY88L6ep-uW>37X9>I-{sUQw&?%X8IQL?XX^ zZdY5jUp=Q=!CT7~awT`InUc5qYt59t)nUs@n}R%RLez7_<1$Gv_ky0zx3d09u)jH% zXX&X`A}FeU%%n37SexpLDez&!@gmaKX{yL}91?aR1=nqaHneSKPOgTQ&CJ&6>vK4L zB|1!(Wt;Z;O7*+(QFp;FWwKC$*!0LYc$ipJe0BFg#}(NGE=;cJzK}4p6)l5hkV-6` zVWpMeKwsQMx6L@Y>QpQ^7<~32vhqUO5*TeWP8yAAF7Ru3wZHdP`%lR;=A7efzVuH_ z@b~Fs>{0t&R_yF}m#;tkmX-x9k^{J#CwDQggE?ubw8SW=H(J+SW^YsZYs$Ozbz*`b8bk4~y{NlKq>+Lx4)CPDnZJY0+r9A34S{$_P>;Nq=2-~tzK2Z_A<-9rKw zbMob*0T+W=8why*-Jp>hFo2795@I{;-f`Y)o;%wzQ5FGI{7-#lp6TwYfay^YE+|twZR6UH@Uh+7sLZXn#2uNHidt zSU3n^MtXfL81K}Ie*v>&1f;>j;%C!-KcS)P6>c8&DB__(S!jKrzC{^IZ3^;TIxW6& zdy+2B6#&%+n1%5Fg!thu)N(*yY=WAt?!I^Y3u@csMgOAeW0xMVFo{YQ-gOu6u0SmA ze(+$_;yo;5$O9uo`IGPB0#S@^tqF5>`T5NRRpX@WCvoC zzYAs3^2>lE;Y@siQ`jlcHCBh0`Dj7$(EzdWxrha|3yKyLll+i~aDv;pgs_OX(UeUP zE?4T%5+@WNQ@S_)rSW6BLH6)7|9NHufoltP#W5;sw{_XnXGcHTcSH+4wGw)oj#!1~ z%_m(cs!_o)G3xcKE%~`l-dk&lH7k3fN6X(Oa4DsIi4&e?lt9`ez7(*X3V=ptB0x-U zI+Jr;W*^9_BZ$O9u`IM$;hq+n$$5<%5F*LTw?t|Kih_V)m-HrAiuz-m~4EkS#KgR^JrQ zGO3oFpseHcTEGIoG`_RH#9jwVi-uQ}OM$DQPAuzD7F&+=y3>R8Dum;*M)&v7j3L8d z%wwJdmAd8rWqMI`C8_foxISW#5EVORy%A=?E~$%5(=r5??4zw=N+U18J_DA9wC0kSR8oBzJl3K^F(&m$49X&9bI% z9avaCdgI}$c9Z#zc*fo6Ml!qT>us&y!Gcn6Jz9N-2D6*E8)Y(@Dib2_0QNN=Mv$8y zR2~S+Z=f~~gqh+v8C}AT6_?#Q1;e1(U?`66qTON*`SgNPp#!8LR3r`_#|JtC{s*`f z18&E`Ne2;x?_Ci%qxS;O>Wk~K0E39v6*|XGqph}8J8bI!R0eo|01D}_HTMP>4vvR> zffmzPZkyXL-a`6jODYJGxxuPZfAK*~D`g|SD_HK!xA~-uZCn&-JbwB1!=H2p z^7qdM|Dcz^b1Mn~Z>%F(4F7F>x-ZKY(1xnhpZQ*i2s2(o*%7T3zy=_;9?u*a35Tls zz3hMR{vEmR^scTT_-K+Sd9S8sFVV&g%Jk;gCd7V0aNoj+^r%8D1Wh4`z<0 zKz`}~(KOI+D5hs;h(h+;V?llp7h*66ZU3do3C?02 zjjnZUDF|P|_n&&&&dwnauLA~X(z47m8dJYTTN0Boz;ww=V}h9=TcrLqK6bIPXpl#* z_7P2{0Puk7`KUc?PTxPei7!lsSI5TsW*4Ok7?oR_C=eh4v1*UIv;m5ViSF-}Cr3@G zi&4Ob3B&WJ*72)WK`fP&uwd=x+S90tMY2WH>iy~$%NA=~uT;)|I8y{$ifJHs+~31Jy^1?-pL%SY+3b%Z#69w8Q@bh>V5rL00}R*sE2 z7!Gy~U(uix+hmav3@L`+$AU-s*q~A9ic=lw@SAV{Y=}>Q<~E9wmFkga0w%yjAWO8w ziB1JN_089u#{hU(-GANR-)C=s2d4$56r@L;@+i>%F*P)=s>Y}S8g88;Eg)h5zHu(j zMb4E0PxMwFuG2W{b^(~H-eiPKdT2p^1svqBBQO2e0dFUqEGcpGi;?HGVvw`jei1LW z-MZz!o8-SGiRW{S^%9*|-{GIKoyU0>Y~Qf|jN8twVcrkHhcTlT0B6Fev1^aq0Bf4g z37&o1|6GtU4k-2(p0R1FWp(pLo8PD<;JLm&CT^GfQucoWH#ek#B z0p5b31$7VkBK+vov+g7r9A=*Sg}5VY7IrAnaxthAOd9VgNTsM-;~w}+Dh5g@Ily@9 zQU^#S)^~%|`%CtFmwbuXHh3w)FS!v`r{1+>JaP6A^oy(rJQP?_GJu+@=_Wh|rlHE^ zTc}^#L<&K=T4M~$+e8W+G}}Z9+e8Xxq7or&6DjzuMBISDu(yd6P}2Qrkodrju}kYbiLki4-o)dSm$1 z+e8X-P(T;v9%-9MAv_hfi4jryKN$cZ6XEp4%%FtPOj;`Av&`aZ8AEiR&zKM92Aa`UV=M;(sjWf#zpEZ znsLS`HWAed$|q&x5nSGd4Tj@*g{#hhp{s3SIBk(N7h4!ka%^`8A9`fCbpPn*?n?L6 z+!ichC$8kvvD{b?!%h?eVh%i(#IoF6Mp}0N`@I~v`IJKvin~oKMX(1u(~7;`dsdb^ zl26bUhBLW`*lcZKIL%G2shfT!+We)lXMUsHG~%=fHL!EyBp#(aTy|p?$-TV9oMMXa z;4t03%j9)B8j`JDAk5tnSsZcdCA_6icDQEa4Og?S-_o3Cr`GZrWtSd;79;RjwzH9P z(S7w)j)c=sJ7@uI8yt~Zd1%>b?9HK4uKgokEgiz%Rk1laBiYEz5OG>^YL3{3UY9_K zxC&DV;%IX6$Sn-#mjlBo4|T+M^X+P$4m;P)6d-ok`&saiP}+!eFzj z|9m}isA4}+NN2Sn34DKa^cGh!Yb;lRCwm76Sdv;3x-eT!gsL5J&SU($sXvd^A@iEO z=(dy|+4gL`cjGIrqBfI7E;?G(*i5ch$SWFV^>v1G_;kl>tIW3-&9k*+NLJJG8Lw5c zXv$NUR+;mtZmmgo$L|zU7L*Vbg;TijzGjGu2q=>$e=!7CA-bARhTjgPA8Vf9esORP zpoYCmz##7Jm(UI&ew_awdR@5s?+_z4Vome*_D$uR+Y;!Wbw>o}*p4T>GIH@KFu=}; zlL!R07jV7AKmDW(?@7-&KrASPbl-sU?b)<4S^$3-nTswT)9x2pG z-45gNrmfAQNplocKP>aFE|@(GhQFc#f@&ti_OLHsP>-3jW0eLx@-N~?Om&|OhyC5w z`2cl9iDZ>pT?~n%IU;s(yi}M&v+=6i8Vwqkie)BnP)uMW}B$sO9im2lUJZ+HIi~+a%)>|0qqkKBxJP z;lzY9po5&yyeJd0moh)wyyO-+3|LONGl%;yC3EUtb_k)ah+{#2PVLBNlaF$$RtT9U zUlC+1jC;D}nxiKc+hr;e@o`QS7A-g5NRZ`%>g{!f&ZZi)oor*KWr-cwwwPM+<_PnW zEXk%tVla;V@(_n`e*N+70shyc4?VyY*xZ&3g&nzgPoe*{j&oH1%e{lW1~7Tf5DqLN zw_(9~+Pxn?er&3|BJ-Z$rqVk%3&;3LVj;U;(fotvr;EvDA5r5lScV-l7WxNGr`PG^ zk+uM0^*Lcy7OQ8%^+9*?LcvI4Vq^OR@35#|jyein5R0yvuxVQ~hGnC#f}ll!0YpmjQ3`4pJs;zeCbs9=I~|XH6lQtH+kJbL!bo_&EA!xKZrBFYF*6yq0`*$#sVzrSy(4H)ebm3>ZkrRJcWGVSXh&K1 zgijCY+z)81sB4RLFCyP!-G5{YPY3ObE@AU?fomnb)WC@egZmpH(+NNC(7(=XZM}gO zdp>}B&7N8})cd;tdM4zmo=yRdW_Mq|#st)9xoRY^#kwEN#~m-3tI+td(04jL#bIIK z>6uTcCss4O6+8LcL^}fmBp9X$9hmBhBYu2`#OxcO?!|Bb|+Kk6N8utb0=1{3td8 zNrhVJ>%3smi2Fwu3OFh>r-U`;vGs)p8z%1|q%P^PA`yY&VMdVHi)BE;g+yEv+^Unr z2-!(~*(qCFyf1t1lW&#;qy*;x03$>`s# zU`f`XG53h5<=dm+H%I_0XM_sBT&$G^mUz02-@=Ih5}paaas=`4+yLhMPT=9C;|G-R z-2&Y3Ac?r(EqpX&?Z_TWQBjVnIKm(oUraa&vrJU>MWcnsP*(;DFUu#O?&K>ZtOroY9M-5{oHEYB89^-BO#<=S$z5j^iyQHsCSL1)*fST}pR)&!_~ z0Gd3g(n9OT&ChOE&1-JxDf)C`&Q#;kw-#(Ns_=t7g-vpY-KJ37rcm5qWU|qphbPMu zq|Cc{a9gBy@orWu%9lP@xOUNxhnbm>Q_8XVlyM}NUgg%2Z3;zV>M0cCrf-`< zQK5d!S`R-Oym2hy+k|W>3i!hv7moxIcFC4c z$4i2OSG_BuBnF7uKM)N@%mcwW=Ey2Ha3MW;q=6)Hyf++N(^L3$uK>~J9P7K^!SnRB zIGS8?rletRswS=tHNSP~FtqoF!I5(LSUz;l)nh=SND z3>5J9d%J{vD*S#CTEzHiWACTK+*Yr%)A-A9cn(@?05A;7G4VBbW`;=Izr{cTn> z@G-jGgP+3W!NU2TGrpraQtlsDD6PsAbi?K|bKJaNw5*5t&!N?nvQK`>WXyG?dgBsS z)s(=}6ywJu6hgAR5O6X^12eW8II$FxWPvWCPgUJ=w>+Kp$ooLTpvLnSAv6A#%8ap0 zzs*wmY$}0Y@N@=Pvv<{8>xCp{i^p} zP}je?47w{@?aPY}dx;4)Bl<>6_seTvKp|SUh4%aTTGlq=FRLQDag!y#{^}jf`SmKI z)px&pn|^&_zI?-eeMEjztzq3?QbCYRoOk**$H%Jt*p}V*LG1iR>K(Z8Hd~L5$4bvD zl^c7CoN5Vr96w~6tw-~Kkivh`W)Y6ghCs53jGmz)ORD+V)u|WKq*G)#3DFfgW6`)6 zf;lI+J7s6y>kRF%Pvbi`l21G|_@Nz-SL8(T`Zm%34}4rSHk(0FbMSCLSO*QURi($lP^ zX=e(?!e(}oW^M@sIg?1Mz!K?2Zif%zMo)e&HZ>o_fi5Qy>Ft&w9OZxAKZv0NF&4CdzKe`XVUdG^#8 zRZxmpdsmLo`om&|Lzh4uoj}{Y@li#yiutB&1Y%3BTpcpZ*MV zCt+Ybp?NYjm=_FM%i!d)NNyX{eO( z{PBB$2)q5A#_OJLI zbq!lwD9edh7P{@8;;zK4bKpc85=yq%m>a|x4PQa4|4sT}`Khc2HR*(QhFr zVx3Uim3)~ivO6zF6im(lRjGs{=*JTig*^##3I&N611VI3>-0*~qT0pQan}&cWS*(9 zxOFt9i(^7aC3@07`BY|hGBvDnE*pMABWZU(!ccZFY#c(A$Om&JGam@5B1=4n z*vCO0#EzEAP)N4fdbZhmw%K~*K{R_4zR=~-AO2n4KfMd3_e0?V=9b%T!wSg&F3#X* z-IJ?+Yr^kyzD!=B$?+@9fV?)E_s-S>`d_%dyi&#hp#hT7MXuu$j<|t~*g{2ZKcV+e z{FHtIU?o%kM1}Fm%fd9d4E#x)q{hkZWoK~6SuK~o0^-v+JZ6^AW02wnrx~+l19TgA z{=G5cDqCh7mjq8SFQbm}jMID2{a9+^9+~#*L z$biS&QT7*g>aw4iy$^ z*QhG9Y!UrLTU2xWl9GC8S2RW#(gA&=p=I?2kuT||E?_Vb_|EfQE~_X>35&Xxf7|9T z`aR|_y6Sa~2jk-&u^W|#h?pTy@FkcvdWay$*pf~5QK9OANklG`HXaYgXUd@Su3-Dr zH@)Pa*k0Wy#BWSLJ)vox^H?k{77}mG8{c{S3pV33^Y>1oh|J|2>k)gPo`r;hd3v3%Ru1BaMXm&EAV{A>HOt>GWw@qsj2iWTUbLd>I1gNIRdoF(HoMYDQF$t&Z|0(cJ8}8Ypqdi)UfM+T?-z@R(yJWeQwZodqqfF%ZsX zSktJXTi!GnFM;L~w{XSn!tE1WO=(Q0T~vgkXQQ#1x1fbx7^<=;^p*B6H)kfroyLCm zsz1Dz`E*AaMkY#$a@gg|eya<|<>Q?7d+~s0MtWAYbKCR@RDxU06btayzqhg zfGfF;h`~i&pCv0p&2IA6hk{)i6?H-^5B6$v$uOqnmT)(P7}uXIwscmStts09dj;-> z23aBxx7^gsZ&;9PJgc0MS)gbN9>5PF|0J41TjtWqzB`uE)>8jHx-x=K2L6I}-13T> z8%48U0Pyc{*!2H*iU7Z8O13#9?hc^7U_Q~?&6e~Xxa=5$bZjQ)D4b_?Iz_acW##aV z!pWrjG&3Kx&av?!*r_C9N(+0OPD6IFC4!sJ5zv}RFff-00E4LYqrUSx-Lo!vDUZ7! zT2fWVY>HQiN;-_}j zcwe`8PoyBXWJGJ7hC>+E#?vkr>_Ca+_(OTEh{b;@#`^W{|{yBcc z5=dkgd>efB`|jvUsN>2oS3keg__Vm4u2O$BPp9MKIM2SD(wid8*GqsaG{qAGQRLu* z%mMGlr#lw1{2j+vxAS9fG{Hc$(`+^^jnWOQHd^cq$0@DLK2wrTaHAjZQ$x?awEqkh z*%HBcEvC?xQjUaR5*U;l5romnXHPlLpIUd8A0E+@LC!C8aI~-=Jif6T(dg60U-zx& zfBhb!==8?#e;oF?PyY7y$zVlrpOK}XvMiy#R5Ew;Q${?dfU>eP=cs=iDLPPD2#nED zb|U^0D=a)BED4dTq;7}yy>Z~#+-52@BlX5R;NAC;|7b(G&%jq0@dsO!W1px*^uAJQ znMMA(22fmrZ7k0EPoylEFIX$zqyMqb#(Xn(?ue+>z@% zJBb#=aqS2y8IM_OP^+|eZ=@s!cGV)CE5-*IP3=8<5X6xiUcRnfV*Tx2>Npf9iLoh5 z>pb9vtS;h>`L%S)+|J)>ZWRuLE!{`X<$j0`>lqL`F`CnavuOT1e-TCtha0X=mE52TqP z&R$sdYI@OZr$r^l@PXbLRw*|GuGViOFZJ7A=5{It4is6hOrDZEZgzV*IC^o|c>Ut& z!ABW*-*q)LEC5jFLD9a<6pWX%uGYB>0l0K`Q;jV zImbzzY4>~Znu6;;vj?o?%eNo?q`LU~=X?Y(xwseFjf{oIwLah*EU=lIXfm~BTlSEX zM4Qnx@S7QVdXE8%ge8W`*U;a$hbEh1IhfmgFXay>!{7(R(@3M~TML=SgxnS8CX;1! zz-cjU{j|4?aaF$Wod5jy(YL$r?e1A%78l&+ zoxXkV|2Y3S=RfEC=P`uJ?E}^oNgMzbSvr!l+Rn&NB57Tw6>%7~IDb{_OHArDJ^nR0A}oJHzzqo0$fY zlb`XsY!*%zeshRBBz(0S9!X3mvuwK#iC5FCcnZ)lRflUD)GO&MQ2r^M$9%8?J;VWc zvoQjpBS9CoK-iEhVT}EZ>g@h!C+Wy+NecJ@0EES?-4Ij^?sCEIxP~vqFE)X)6LGq3 zC!(ZVkBf8K3cIxw40mz`mKyyGc~sE~AjWo_32@ee>(h|@BLtkam`o`~qG?^Yhruu@ z_?PLjF%%N=Ky*`t1#}lmp*X=y3?UT^Z~ksTqr({^{klNrVQ&}GtXooB3z>i%TDW~u{rue_6IcQa z=W-fo1)WKAa2}v?&Piz)JIK7zIe;HB&nxy2=MC?rgBS=X+zkZ-U8+ut8Easrx1wOm zkhT&pIAH`f7#uCws$=NUI2yE@ZA4rrV%ZZ1hBmFVsdu#&*-YEC6ax~f+};KMNVqTB z*3M^?cPnO_03(6sviZB0G{;{O)d9)z4t6}4qQx43Z5m$v`*i(Qt(t8)E43UB2{Xfr z1IjG@9R?qSg@s2@)378v9~_qeyicrkISYtIWYD%NTc8aA+7t!8Tk@Z1@Q)+LG zco{cU0fb{H(*2Q4q$hRYg<;aR4^k5r`W;$+3j$SKX;mbbg#7B(FvdhyNkB4Mg5>QN zy(WhGWXfS_FrX3-MfpvM(1^@8!ptKiXpP+fnJ4{@j5_lhquQGCV@k+hLc6F(&PU2O zDt0GWCiYm&L%u-vg$)3zcG-sCp$s`ej#!)mmTgQkdUbw zdWzEY3qrdabr(gN^{#W&;5@#LCoPOgCpBCAX{|dW3U_#UL{F&wi3ORznV(?ukaF9U zBFC^}IOF_9{LvoK2h2q`FnT(Q_Fx~2BKW-Chsz#Lk>Om13v*5IFDkM))uw|2^m6*$ zjlzpSP^^tA!}vp7_?Z7k)=3?L0D;+llCm72jg{!h0Sie%Yyj~~h$zRwoEMGa z_88xdcVQL@hmsW^Y0i_PEwDrmKr|J_093%BYdz&FsOiF`liVgW6-{ zAS?$Y&U8-K5cJ_Pg3#eq#C#t+EeRixG63O-jNwZF0xYKC!#Q9wP`r zoEZUWCeLLk#d#ba-%cE2s`4UdUGV7Xbabe@!$#Nd|9~z|Mv93Or4D_K;;OCj=xmK{ zfzyZ9Q_2FTaL>J%*+TG0B}3`v%9QIkkA#a9`3y2Ub^6M>WG~+MI35OUp5du9gyJ zq@7jjpK*h3T&vJM>Eg24h&D}@;L>8_wfzx)VhZU)2znMe5j(k8bEg%D8R{TJkN&_N zqWaD28l(dsIEH4n>=#)yla;eWdXcAm%rgvUTLzYC^EP0O$AO@QGbo4)kVi0P_OD6+ zm2pO6+v6&wA_N45H98D(r|+&G#|O7uNF0c73jrjFOad~s%;TwH<6TmPf`G@7lqoUc zZ4_LIdq^|&EfEiW_sLxVv3LnB!$l21yyMiik!5QK(7@cTe)NX4p;cXmOgM_8JXm%q z>e0)m&HM*E2S@l&)TSd28le@Cq7o7`!O#xT)zS~K43X$H;>QE^5e$~nV81CRmT>Kb z_LLm2Zb@6gi}BqQRQ#^B6&#of6hT?Ua1mp(Gl;oq2F309dCH~lJUMX?hQB`( zyOQey>?$AxM@Rza404Cgc9VTA#do!#RWja0i>u_kE7?jTq{Y<0LE9js!(XbLK9^du zkz`-H9{VgHR>C6qGs>IO!9_WT$tA5rTduOHS}?IbQJ~dmIY~}+45m(%-}#5bMfweJ zaTR&=Z|4)~P0707v@{N3(mRUEw0fU$f5=)Bz@4>KD(Emap)YM8EC|*OczXD%NpN*w z9u6>X4erG>F#~4ZlwAR?(>UsHKm%{--%kwhufofvnzKNkena9d0FpzI!XMJZmyQF3a8m#Ps?-aXW zdSzF*6{H%LFNdKfzfGQYRR@CZXtX*Igv6C|P`dI1!4x(-Jifis1Hn`eg$(|w zHxj1m!;+WGD4XbNDT+#pTjsRt2k7b$|?@W3@AvI zRa~4ro*b)qhB+LnReWk+OYz-=4SPk5H_@US*@EYh=?O1t6;HR4W1*fhZL?Cy`z8I~ z=JvVNl09mxcxrZ)ReY6J@!6oQtl|q=#ZzDvnQ#ixmlZNsEnlwMD$cl{dbjl~1l3os zJS$;9JT}NPpv$AtUgI==zw^qa(}f;B^Xz$joPS6Qb6S7)G;>~|ef}})g-XNE(PS$P z|83In+f43#31_n7-hG~lw0i?2j>j1vPM`VL@$0uvXwn!j^!xLvgm;b{Q!4rSmw|4n)Kmd!KRqa&+kW$4HVML2 zsf+jyp3@@V0kg2uoe7Z}%x6x=CvgIA3^Xbp3LB1~)fxt!yDgHTpvzm^Z!o(D5e5z*KpGUt?!whz zM^d~ycRh^0qnSUZ@QAp{Y(*;@dOGE@Rg76EGjpP|bb13!=cb;MFO^t%YWu6r<}tk+ z_&Pt)i7;kBW)(RxrZk-p6Y$WN|)%hn`Phr4E9VOXtWk+VVA#p=Q zQI36<7@;%-IfkR~t>*2M3HVT*#v}K5$@7hRT%7Hz8L(0zF9*RAwoUko5G9bX;@@S-C96qRr)_ z9?EQMx9M7P{as^n?pN$oGWkZ)!^zA$h0iE6?-f3(bnjIsmeq;nqf1icknk`M9Z>m* z2Wm{x&EhFIWDd{Em?;WTqL#WF2WNZ{H#f*GXp@>@wm~x^nW+M8Xf*@W_eBM2shlRq zpPKWlDb_n=!P8o@t~{-jj=;$z&foA_3um%@qJd0LqZ*}H-w=iH_zc#5Z!{W27f+tt z-`}tAAgnVy5JWn;jjWg_M|&_pjy7Ph$02!h@8p?Nr_Y@{b^0XQZZbf0quanS+c4Zv z7;LZ~T0r+kT_kjyhe-Wl8#ymt{3uh4B}FiB zOOF1AsEq}{(_Y*QaW1HF&xXK=V`i*&DrpGp#z+qk4w1lx$HE73o`|e`z{1}x3W6|K z`$BT^5HT1Nq`BIiwYYCMW~LB<^Oru?XPQ7!M)(k$GwPm*McaCPh8FQzJtnA9mF9!6H+&VsSWzrQL)$1 zhlipqvSJ(r_j~>Q9=xDXy=KJ30@#~bu^WV$=h>7Vu^{JNZg?$Jyqd+k+!P(?-7EaY zmuARLi1@{j;u2BvU2A=iJmW}~#Cu9u!;Wn~pplp>p3B*|?bBSt=$XOG4#F<}g;i{Z3 zE6n*a4XBl0`+|P$4xnRrErO!q`2tD5*HWrBaSQ@8NEph%crc6OtVRNnRvgz_PWV{0 zC;Xu+uWy6a8bWvoO{eu1HqCI5AzB2LoyH~g!-j3Y$fahQ&iGrROdwNZnM2v)aoFwF1gvqZ7jFd zAF_cV*?d_rCCmU*)~|p`A<@W^fYMqGb~5{TJ2s|s%?kf}G8sz-5bsFGoy;67p8+#Z z*N=WJg6!JHHm{|($4t|QW@FCnr}SQs=DsirR>g>_Vnn7b(0cqf79+}Fw8Lf7UHEnR zazvRvoRz8K?eARP?v}XFp=>^OWbRhT@{UKA%!;oLcNTUp%#KJS;8xaL5i3z<2nj`f ziW<3$8DM&6ONuzLfyP)D$=A#x z%Yx1<8Ne=iMwQpvO1a*u9aI)qQ{E=FnbS>KKIz;VWk;Ls2U*$y^5}a$KI&bg+9p=H zO-w+u+7}kw7X*_1&bW)bjG7nF)melQ!lyEX^R_;LuolVos1<2_D#ZPE3)Ob-TJ1xo z{?j^&XaUhv^oiD7M-sxs%7z`J)>BVPWVvj2$6c-2rrGv_U8L0O1=nwB_Q-nBuEXvQ zCv!wRX|hA4Lt^yWi@`HYZMmswAfLemCIVtOKe|!Rn4J9V5=`2ZG85bj+q-+C$8&~D z`KK-^2duy&byYik)E^IrGbXa=Yhc)>-D?S>OKT^9XK0Qpa9gwQs+V*ge!A zMy^oS?He*CjAi#2ufR|Uc^aV&g&WS<%Y8dDM>a+h(}T@+)Q6V`M)DR8zU5YM{mv~J zT!FU@6z;n_t)?z`Q9D9060!CSd9Mx`()h4a=38 zi7Z7KbJxYXm5J0qNwAz<#7d4kC@YCoLxcm;y28w?b!mC#pQsEj9jT?XJq%inQ6p$# zg%EeAxpsFteS}XbGm9%N>QJ`9o^%wQV6b-(vBWE~+G2VK>jAMx78ZF+Q5rfJ9SmFv zSYW$kU2Tk!2~;8k0S24PjCDW_aOQY*3wT?;DPrZNVT&95SfhjL>H$(55Bmr}MUTQC zB~PkmxMPM|3nS6k8Tg|&Saf_Oy#WHBynfsDg-W-QYYtUA5AauuHCT6s$Z3kA+r%=a zVs(Gcn9MNT1#%=Y@-?|r1R>qK4oBR3bI_5__iy%lME$$WT1#Ji`R=Ub1}42i{mm~^_5u}X87g|KVBa8$Af$Xp|AIB1WC8H z$}~6WxyxYd4r!9>t^>$JHT|UkvdDvnhb=meDMsBzP6HE=DFqOhkiZ2TvlR{E7aohW zo!Cr4%!%6T99+ZE5@G{;{oX-W60+lmZk>#UIY?3VcT0xUZf%jA^b1F}1>UU{k#XGt zcgJ=naqE0vH+0rIM|J}y_D0wtnvn?a2@;wDy?NZmfu|IcId<%+r=Eg%wcAEE@B{hw zRB-hn(>5^vz8!X2(J=@Z*Z3Fk?n)RnhiyqCk8gJm2G|yky|uBi;Xioz`y}{s)aVZQ z2H<>BHVxzW+gg0C6eNK2ks+ zYrjm`4;ZD-Bj%|H!Fl~a2JJz}Jp1+FweZtpuww^rRl&e9Wv;?x2@;X>t|GI$@NcVh zP*%0t0%5H^Jz)bWl+5lVDleTa4MgcpNrpz@cH#Dmz0$2Cs~$afp}&~|ng z(>{S9A~5md=vIFa8A`j9XPExuKti9yj{;9d7r<_JLY6=KyhrHIU^KTZb7dC-fBXU=C3Em~D5WL{09NTC!$tjb~@ImBd zZW82IsED|R{QW|$xHU^Qz+2PbMM8gMU!kg2Td;OLyN1uH5hMmJ?mPwNei3@yoC*xZA{>8I@YmW?#M zt;pTFvrDU~!hP{YecTSJPil<;EF$DtnxoiXQXO#iX!r2-5kV;_zoJ3dM8c>h-hf)Y zr4KM))oy=yfQ(X3aL|2pOZ1@)D9l^y-jQuX4nsq^#gO+6N!fz$6okWA%Ir~b=n$B$ z=8c;G!q_`fI4K-vnP+-5V3~I*v*16MmvzAHH&rtc`5uNl;)bj-es=PR zBwYy9KZm>N@`kGNx<8TrUA*)-) zXaUf`nkX4+Cg6P0`2=nS2cn}SP#B#;Am?kqBKH{Z7*-G16`iV~#yfze+380#!>K+f z`R3dtxbB`#ELfQlH6w{3>m=9pAwIBZxqT0pDQ>F;wOJiBo(8rT5>$yOt9 zBa9%x?T{J)XiszY4gr*h^UkbknauDwMKHOmaymvY9fYjqNy0<&VVzGfs8ynx=O@yS%s2PphGwalT^Xp(xKNKJ()tTO+jGH zS463tsn&*OL_Om&QgvA8*gMW6z5*!HJF~TW;@=LL_qsSX2dA0(^(j7oYVZ;t3{z-1E9LAV4 z1m;Y#McCn+qR+~}V4;S6+X|}*6jXgSwOZB``J%Ww$~^phL>HG=1e6ZKjvldAZ4_@2 zKxRhJ?V}JLz#hK}3nIQ7`0=f=-R{WwL?0&CaDdb=m@&>je zH59cm>Gk9)#hRCyXox$afa^-&t5aKUCgf>%7dZuYXmCvqBp8ghJM9Ps`CMvAZXKjV z(K&$g$Q8*+$~#eT9LH#N@GPm8gP+!ea5%)z`16DwuGk2SF>&jaeF+B(d+p|)HV)j< zQ6M-MT@yhux)DGqNi#u*k|7ZlA8C^EVgefzr$<7~dJ=(1z|6Z{B;9~Gz?q%5O61v{qqF5%doMpW+`$eptvL{ z!=EjriG-F&Q;z^sr3&Hrc|0>|6S#hbZJ8t>h_B0>%WZ-3TF4E1t5F<}#=$ad&9McD zp~sOoPsN6?1QHYgEYgNL%*WyxB|7f074wSZ-jlIw8DGG@)puD;>w&JTsP@@Lbv7ns zB=)p!2(6lvcOsI^Jz>ByJ_w`4eiAOADwR#hVKql8Wd~N6Bu9V=jeJPZxoLqU*2IZb0kvZZxH)|hm+bOTXC zsO{C-NQRH=RDwOoJ{Sx3C_+R!mPx_njkKyR{tFGE?}HcAqf>m5^|8bsX)tAx!hxxPv^{%AmjcHK<@$_7O2c83LY z1-%J#@G26MoQw(xKzibh0Ne$30OH6og$<6+Dj?~ZKwgDkmHA^lyc8HEjNJU*qn3<3O<>eLy&|8z_Dz7iI^q$t}GxXX`2Z>9w3WTki{)|KO;9FDoWbt8+vNT!I5ok)metL`bj zuR@hMUR;(ngNy z&$MxAOj)J3i_@Jv2u3iIh2Xt}p#2&9V)~)#4(K0tPXIq)sG`4+m-R&+j@5fpu|Y9? zT~%rFA$SGmiIwAifY~~%Na)yE4V&+Ii3-dK_9&jZa8};^Qd+4;xQHv48pJSGd~G71 zt-GB>ku*Qa(WO2vk_!5cz0RJ6O4$i+(OAm_Qd9HnWex@Zp7{irRMJ6PiuXrK;Ul8XZm z>Or(Z2$qh5?KQEgdePbMGD;Q(*(`I`Wi_(V9h%hw_QCbmVc56>q=eq+vCN+Ie86dt zl7pBznr$@elqqEQ=*zLZ7z~^Jfw=F@m= zl9Y$d=ID?K)+aDLIFY%rXMF+PmieF^p**ZJ>pAt#TZp*TtlTOn;}gYU!YrshIIHlX z@+~dvK9z20+L64PD_vm$=xa(+!r)I1I*k#2hXEtayE84zu9KF_^@-fq9;v^Sjw@-2 zaF$jUqgWgiMIo>UQzFvW;as1kswob?72JXVskU>sttNlZLS7okhoJf_Vs}xwhSbid z^*BnM6f>e07TZJ*k-Fdq3x^{ZcVawj9vskywjS!0M zcnHPLVLKlHH_!F9;BP6?k%#GmatTHT8xCfwLa#WMsMqSc?6+={78#5?DEBZ39pcv3 zbJo+|gEkB^l=S>b)o8Kitjj&6e1Cks2gG^-8&dyx5`Dc z92ypAnTTzAyC7BqsS?Np$H#|GI5vlTxZxh)Xczkwwx(8+R#YWXk=LfXiZp%??z)_72RZLk9d;k0-xS`ayOBT)VV&SPgT zpd6PyPPvXq0n^~J)9ALbCSbgGpzq4x$4xJTLm&ihn7hJl%oSF4l$P3#Sg%UY#3r;D z1CY2|=kRhO6>Ma^W(RtZ;j}qyxj-8}Gi|V{VR5k8UBdkWr9!;F}n?Kvc$ zXidjyrcR+eZFpKkCK}`o&Htuwr7gY>dKhoRrD;4LmQMV=CkO@p4g6ENRE0a@6bKq8 z|L_zRCNY6Z;0f?3)zf#*1vN!*$Vl!Fu0sc5S$8@8zU7}ncY3JeF*|8575Vl!ZD+!_ zPF!S2;P~M>_YIjGNZ(J*s}(>oXbR7O@3#;t!G=XRcH4!s4&jhWPj8%j>?}ImP_P$! zn@2skEp@jb6pujnQZ|OCKbSpt6f(s&P6JRNg%%J9`l9q=XNAKNPTjy)u^~upwP|Z= zxRir!_EQlwGxf#U*OiH01La=s^v6=pP>d!tLIDuYgw17gTd-Q@NGbf(@7TkUZd z`yEuZ2VH0TO34+DGlxSSi{U^|y-3xPfp#@E#r(nNZNOp!Va#iUF{aF3uJ_({32j1BrW(?q9KqFpxFh#-5Wz{LOs1kOHTf9;?!j{ zmD`nNX0kfo)as@H7YKUxa>*p9tw($Y6>h_;RW@!VQuj2m67oiKZ?oU)9BeYiRYVqG zFwK)I+0PPf)y46a5n$NRoU$mUAhAKixtm^6aJ*8{oQtC`^oP(`0dhfJRS454lk9`W zj70JKCL!9hoiD=am{w*R z14zzk_XK!eg()bpVugtZUdM6H2rLJXax4TqG=Aa6j2v#_f>`ZZ;N6?Y&JQ)wYi3hOi4mAQdD zU=Zc8wVLXa6E?a_P68q4ZAi5rBaC8%)wgoyERTcO=x0KL9CT#CAm>m!63o`U)@?;3 z$kblMeP;wz?vb82Wez%O+cfXh#0H0B07hzEeIF3qZQ8`T4*(E?h!8Vemo7HpGi* zB$J)b6V5@h;8+Fs$h0{^bVrOY{I&w5k!HZK6)VVlu$kD&67Y_7fK*Xk9j-hPEHJZp zM}hr;mtq5+7x$K6M&Md@u%sp>*^9tV@ZW^VLtVAx7eA0RE-t{Z%0S=&Wz8Tzh+0|dhO(>&4X$ZFTcEgyYC$-vP6EmhM z@(IuDnI%I8;5&H-lww$AX(DG;Fc7Oj;|`WjPE4WVb>M2m1%ja0bs`d!7HBu{{+YIc zq@xU{6lR{E{tG@vv>+Ww+*_SiNy@ReTorFIQ$pgzfh|M@Rh_qC$~u1z$5S9t;DBma zW+=Dj5>e}M5{5hB2qM@xy!ucCsn^2Yk20vk-Ses|BB3K-6{{+$6PcjCWEKIKup4i6 z2AjMGrT4DI61am#p$tHhDm1GwO1>6)mO>CRA6*J@d2S&TykEQe^5#p|Z(e%s&+7!y zAy^MGZe*9iCaQ2#s}do1S%oS+^&{L!Ci=6TjNSI}xoWGGgSgxmWa178zC+b$(JZ74 z*RcJjJp{)&i#wlOm)TtX#O+Hrui&fs#l%yGBINp}NrVO=ZOgguUI-o;GI({hU*b5^U?r$8WuMMKJ>3KFV(n7viDD z%8Lv^SMUgo2p!A75MP!mwVYRicm}pvbuJtk5GSuX&Lb3U~-5 z-pzM%@foxzAjur4OEz%0vHB!jEB6&j%&rtbT(nk|RtZN2Ccg_i%>Q{@SgTs+JHK~q|rnqXCeYMIHw7T56S=d&2f~aAqFqP&gq~UeK(`%Z7H&5EnzDPTC zl_#jm6LeLzNZm)PJVBb@U0qD7JVD;8)Sp$xfrQS{rOFfJj-#l4+mYB+iE`C6ph-DH z9Rn>dP?aaB$`hpSk`^6$y~+~=#{!7xaDc7y1kp0793yFqtnviGdtxBY!(_Qto*?>- zi&r*ih7hUp1XX#0kjWvDfy$)>N}o2ko8rqMPA51u0OO_aN|h(51%EjD45cZn$`e%O z2@)1t|t=6+DPmp;-r~Qz; z-wjSKZ%G8K%Yq?)#$+7IpiPu=8XdAYw~414Q!otOv6+knciOE6rjyveDo>CIBrY#bl_v<62F7kyd4ke816)8+l_w~b$OVC& zRh}Tp)+A2!>5NQOo*-2JsPY8)tOAIlkwkBn@MvghTPbu*6#n#Dpc@b|`Z1 zi7y+UfXUI11WQcD#c&lb7C-r}!;u;BUx{}PCG<<8&sS0G#Tv3RT;hF|^J7OdYWYOo zRn8B?kC%siRPD-53bPBpd6x+v5z%?MWzrr4(_-%}rI$Pn!<*=YTAF5RK_EfnO!GPC zWcozrP%ZIp{(*Is^Fva$Xtqk&LQ#QI(x@?o5EctL)0xqi%hu2bktL(i>-P?P^7w9@ z$%Lfl3~I;-z}u*li#PNOmx|SKv@j{IJ8BTfX8DGXFw*tA!USk$B44&^8Y}FQm1J`| zSY?y6Q;fXk@a4{4AGL7h3&w{$;q!8S1g}c1-00Y`yEw(yqL7FUaMcG|{U!?VF@Gmh zCrBk|Iywhi?!gUYJC@9g^$()P977A33Xv_v#UPMVgdk>NQD$;d<2>+-N3ERy}+xxGH7pi2148$wlGY2?xsv|wO%Z&(k7%AfDU)+HjAT;BrsZXbp zm-*kU8v#KbVjdGd<^Ur(#aCEMApBXM^&>VtJG=*25WsWvtMTVsN2JD{!hE4p5Y8j7uyPAK0AxQfhF9Bd^89B-xaeG}E8aVgm)o zdK+$Rh7@^ z5EU^!*(YiD1aPje?wJfs^bg6f(^x&mZVc{kxEf=;pCac?e~4*#%m)S5n05+4Izzr5 zx={v5{#wU3lwLjC)a@+&z!ysX&|V^lfXfD?q?R5cVZ0X9j71!tSNV`-3eJ84+IK$qNK3y_(+x{)set~2uI;; zvKGuR?n>JrF|L)i(Q0wzR~TO}3|l}Jd{Nw*=px7sB}-GQ&LUG2i9_+zbAPJH(&$JD zK}_L50~}?<>5R?_Bqwf2Gs5dogU3ZwgDm`5eOJN0ly`I;0R8)(#$W0dsHRr-pH3tiRsf=k93z`m2WNVLRvIPao4 ziv3DuxCzFfcd=>U5$H;617A?Q&{YO-EJ8fj((E5etK;!b)0<^?!~opGuIGu|b!p_+ zhU6ozVO&JA%dtLxB+IRe?%8b*4PU$!n zgpw|W->3~uQ|u^G5Rlb9A#X^9kSa5dzzTI}#=|Bs3m{{0WMSnQAW^YZqZ$&ALvkP%*NA;a_7K@R=!t2@HI}QS z7|sMxQNY3!bx0ws)=0zMy4LgKpHiB`_r*=glyfZubl@ZuY1}qD$az&}oK$LyDl?AA zGbnJ0kS&%0t}^3XYlofu{2f(hoGLR;l^MtHewMt0N*4AX{Kw4(n;^{FL#e`h8QY~) z6<34xbjqqS<5Zb(L^i83<5Zb(Ao6O3$@O4wG#a!Z>Ov$2UxE2@ysdr{CTlzQ3>M5g zh(=*IIDS7I_Cm<`eJa36W=i2trn8sM_Trlzd%nAfK@q90Hx%)szAk|Ski9j z(Thj(c3vmm7F+y@Z;%fnbuk?0aJU7Bz=uxkp)dg>9}e=t^gj*vqc)EHT7mQaiOC=<#VTC41pwMsmGh*^d14Ht z%6W3)A_|=L#t+va-!=On_Ay8w{#o!x0Gh}_1IhnZmGeZmoF^*hiFb;IaTYGy&UYKU z-`uoqD?zq9ac+kv*A$=2*eC8GbmdWl1=;B+MdTuLhSEVZU+e)^uY9nNiVwEA@xK)q zhB(h4apn~hgn2}YZ=9G@o{54a*2Hb(d2+g6>&?L!Lc-OO2mg-PeNB!L)9NwIbTBhuR4q&Lk;jH>0MIqHBD4+JcK6sq=r|9Czll%Mo zb#qy2_D}APAsw9zdnZ$`pM+a&2+!4Kc+xr5p7agY_eR~$Q~v7-5w=9GLZK2KIDsOY zoiSyuGpB;>ar1sC=f4e%O23ito_+d6tO(OgM8FW-;|R`I(q@wprnB0FF0~|1JYQ7CdfmCq&6@c+>ZTFfk5@^&U(qPu|4(`^BuoR~;qi0RKxcQ*e;P3w8Ox z*a>}lkPg6T=(axuNbu}lqqDQQ)9J&-Y<>@29A0MH$D1uZ56?u96lmM?&CLh>4gy{9 z${lzUJ2Y0$ISEej58{bgxb2^F4b~f-a5#$UY-Dr$0N_Cbcl#s847A^r1C)vOy)ovh z`BodSXSOcLfYxt%>*Xq19uMfug;0QLqxTOaHlc(;srVdxLz_7>@jouwORL@3?O|7I zH#ZM=Nv3p^Gbj32`W3~(m00(jPCSGTZJ}m%nlnE?qJ?MKi#Ekrd1&<0%Jh&ki)B_R z(Ygo5;Vn;YZ#gsaLs@iPb`UFY$O|*kMb12ySeaDw9v+9bG*i0EnUf#OqHEJ>Z^NX1 zaLCJ(*GtZ9mRO-|4<0awwn)=^%$b=V&Z6t&;++n8o$`9gnavXGlna>hyHPMBK&7rN;j4pHL=EqZTtwi&YkcdT$yskZ8aVf%qZd5Ag9HD@J}$G&SMip@o;F8Kj$F3$qMm+D39! zr!|&ZgZ+jZAP&6e50Oq#^b<@Q#gZdsY2BwBHOZc;Q16VhD$d_xUvM&i9CGcznGok+floAH@2EFj(%(u1Gx6NT z7IwV_0)VR*9%r@#CbpKWb#Zo#b!H)9SdL`7fUC$IM1VRGO=DvvaMayl0~iugmuSNW zkWL~BCU^**W7|l?)gMP4_!>hcX$)H(#-(CH?kODS^>)X2oc{VqGu4tD8m%{~Q17I( zs7R0^Erkz9LkQ?hO)~6vJ79)8j~6-c94ELcLugMPU(-b*MMI4ZyvWmGN)qp`@+|5@Wy5JUk-ibB|}TE>H=%irp8* z7DkGIGPW^jCQg5^fq)74bMtZ>4lR3)fyC28ufZK;pxh0IQ1N=B6Xa&Y z#=i5(0JcFQ7dI&U*@9|`G)YKB2*(A)>C<6hmxhw8tgaKQLd&br^2_N!m1|XKIYXDk z+d|17o=V*M)SJcK(lnatbPjS9VMcwVT+TX}nY6}^B>ob2Ca?-*_qY#-SP@8s0$~=| zlLT#`VWen+v;wXA?p_F~22oP`jp2}44>YwQnG9U(DNgl!>xr8#`35-@vI0V!V%Dnz zOaTerm^%-G5gg{hNWjLxoG=b`S7QNPSqYkm_YAp6^LMJL>gdav6xLW97y6* zZBe(|&KRV98H)mvxy*E+HcvWPC8g2tk@#%J;OzEd##e?ZV6@`oNY{ zpUavQsoROT46a>*4HyJW^Z9Ehrk7td)5;+7h8YpvnjR$m{ z4jNI^Z?*w%NH60N)9+*w@h7H+r9=ijcu6vdhmFQFq#ZcLBeAZUB1q=$){U0Gi_Bez zmBS14@N`e{eU0V8n2fku7E&rf$Od$H2u?=%NHefsYup@|(jCdGl!6g5-ifRx*r~h* zpa!>(7|u01RZ2h{Wq7 z=#bDEm5T*!Ivf+#s?c(r@OVBjcr>BqcDm&7NzR)5ra(l@(+K6ISvuiP8&Vn0o2Dv- zc9z1^7yP$y?iz6LDxw{<4;aeU2R@GY0_+voOtX>tUPRJW2MUz@ecS|nq*;dq2m495-EKh0 z-Wi7Bc7&=5E>w9U2&9wF$l1~{Yl`&{n$x%*gXaFS~t3gMUiN^eI3fCrcK5d`G=>_U0mSF3G1=8E;hU4%=0&-OkPE_3kS%>4iikBlaDgdYryu)o&Fd_XPg#J zs|IK_p$@we5}Hi7)4m@DTcb1eZrEy%yV&op?*tFJ&X@vUM8uprHQI6Ja0r4$H;#K~ z)-^1wmQS>*Xw<(ziBdD9=g!}H58@3tCq0OF4!a|c1!|7rv{--*gMi*P9uO2>wX_4} zw}hS1b|6BbzG*)?o3Iu((4Y9E`x(QhPZ}aBalDFIJ!pquLTZea;~U-(gARTK(T`EK ziB%%d1O-_oWLit?L^jneS{KO382lmtkR+|1*n2=iLg20>%0^rgW!&u|9w%cw!RmMe znCl9a4<3ShOKz6~TWC<>HqJ!JtR0cMrwKq*u50dX_IsU!%@IzQ5k0Hf0bDU4gl!IR zgcVj%`$r{e9~hM=cUF}@OBaet0S69$zQWrpWG+u^`7@lBO994BCHqa2ao$P_Cdz)W zfh<(aOb)jx8sHCS;ajL3Cr_~@`BU0jbWpGfEmvVp;bo=i5~YVYK7(SpA#zMS#jA?8 z3G&IVpDsQq=acpAal6y1`^^>}{SRFgNBIT29XC_;bK`c-711}<^rXT7Fo%b$;w?hm z$rU}~Nyua~a{AQJib(FPfk(SezFNl-OkCqfI~V?fKCGlvR(#U|B^^JUBOQ`j#`MNA zNtI*xL{T}WwBxEudA6z=8W=~W9$TWc85l}c4UNd6YC)C`^(4Wakn6dW`%={a1N&O| zsH1WW$9XmYD8>x27$G6KGp4``P|iU7Mg-lFE=G2LHD@DcxtTl~QJfcpSmhWF_1OGN zo6x)I2jFA@wG;3}@uc`*dxuhipLmn%$syHsv3X+|xnqkt1U7IvwKmV>?3&Zq3S%XV zxb$jEl#&w5DvY~{TQKuDrw0>L$j~asa2Tb`!OwZIDa>URaNq^u&%lpwm1DTo8}p0_ zf^Ss=ta8*=AJy1JMp)98+a{DL!cR=S!my{&u3Oards8*cYn7vR<)~dbYC|6H zd>zYtNmmecTGarn9JR#&R5@x_HNdJGU{wt;Xv3AGwuDr;(}_pzsBMlZmB+N!FT;r^ zyqt#&?-3Uh7oPQ?9kBwBsuEcX(VcP0T!;k`;C5LR#meyptXzmCQQm~tFPSQxdn*^>zBp=DF2re9c=JD+wpR1qR z=)wOsQy=Kw-S@1$>j!`Tt>*NGP8VtjX)eNt@bE<#D-SX=?Y=i>fHxOu*VUNWz_r0_ z6B{m`s{TgQ@A*!D;8=ivH67ESF+xynFREP(J|*|%H*3g11fO(manrT9`N5hz{rb8# z2B8|RV50*xbLP}3chlyJo7$(g4JjOc-Rv>GE5Ec3z*5^y{7^%JwJ5ATyDZ_KX+Dc}`nfGMg zGaHu<+9+}}3^!4^=mDEPed^4)^n8=e${RKa8^2%3?316#{bllQ`i@&{@fK)N>p5FO*y<|6aRQxDWr1EtzqLG@;sK)2_7~b~JbGtg#tuVUO6gMsfNbJ2~}q zKU&i(w92!ol#4t2iRr)2z#Z(i+!3+@grSmMOOx>v#}5mlWvv_wDaA5oEi;^d)m?0w z6k#jP>#~D9^ZabaSVNsZ-NGo*%-+NDv3l}u&g5(2Ha8Wwi{f;xz)rC}bXye;F)UGrkNO{H`bs#4hKPMt$x3}<7AA)MOK z1TY{?r-C%*2(LAhS8Ee$@T4AKoz27h2pJd)>|9xfn+tRHIjg^NsJt+AoUvdAOmatG z3}X;OGj)LrW6Dt{8&|b@c|gqGTMUPb!qq=tV6XAdW-)vArt4o@L<^b3Fl&z2>A&Xx zGI=+L_S9amf`u~E%A9>D2Q0GzI-r2Da5 zBlUHDY=`IEtsmR*!4CNVA@9S-c7Rd%>2ZkU=ko_>h|ZiuGi1@}yHCwB*S;NnxzRqt z?LBwnFDB&BU1lnfib{{QWLnUvt@)ko5$yr3ez(z{e?Ic4_5rR$A;bBj8sOu+hYsdr zoiUa6U@?}0v>5X{c|@rFSmRB9y4vqqLdiq48oc}FF2StE41 zAY_2DYXJnZM=NTkhCAQYFNT-%J6tI>TOR8pOV33QdOR2x-ZB?pr!yJu^j%^G71R%t~dO zER=@q%&f7LBOTR-Au{Pldz)4{5KY#e&2u(|XJmIf9B%e^HlsaMXy%w|r}LVO9~{D} z2m^59g|nyf-iS~?ur8Yx8vRr*{E}|C`Aez(D0S%Z6AipR`9@9p#4aHc_(%V=zP84Xy7A|^+rPRJcl$AFIHG1{ zS#NuK*P{eiv@zjlu&FIp-u9KZ{c_&+vk(3Yn{10%^UP#slF1~Ku-#V(K4%9`QG4>? znDS@eP4Iequ%?uh%i3ie1&vAG7ielrzQ=+s`sWKoMA)--^?T>+6JmQj2QK!LU2AiL z7wk#97DXO=-mWEs8|*c^F50bszr3@ry=qqv{c^z&_PSjc368LL?V3*+_G|W9{OJN1 zV~rOLuCV9ry7WSp4Zg6B?Yis$d^-iWqdhzA>QSl~_ng*@-OsbPOy#cj(zI&{T*x+2 z%;h)xR`&Zl6*vXG@U!5^et)dNvk=x5=TioYa&HuWx&-bQ3{J5T+jUtkRIBzg1Lcfs z*>xOG+6ZQ}E4drmMW zIb}7xfxg-Ef}sp1c3qf56mwRy>Hirf~o9fyOtp>9_Zfcv zSRtI?+hxYL9Os>dlW33IwajK(IM~!0 zx9i(5w#94{k8+nUBuKADNtqe^YKvso#dVZna}Umh&Cz%`Kla&rv+Gfz&w|0VHZ8jz zmFX1@&b5iz^{7nnoh(z%4-U4~va4szvx0@~VY`;uGKvHfTf25WDyUQ{66>f>3_5}d+1 zDjRHV@7Z;AU|$~G3r)XFu(nOwuC)ciJ?&k)E*{KnE!cH+OW|8wO|Z8$XV>Ld+FDv* z#qHI_!b$CIyVjNn7PmI+>cLVjc-&sMYk9W8Hy4ED>Tu4_eqnCAz!b^`ryGpzdeo=C zkVxexUvWPJMVagJh;F?tfbjNe#r+Hta$OLTN1gmj2lJC>CnTtFape&o?ke10@}n8(Ppn-*cZr;g^3+@k>sG5 ze~iy7F}rMt4X)_;r9NCSdh`RgSk<{0SZENtZ;QiL31l%4`uP?{8hf+AyzSB2qFc-o zqno>K9Ncuux1kr9WvvzNG{&8g(QJ7lDGd7sM)T-7NZ1?pJDu6Z1`XVH^$TCjORET6 zIt`|y*$bO+H7UPDhcga@H8e&gV&^0T#eaY^9JKN)SXMWawdwklptdusb z9lKvck>A~RuTeY&s=Ybw>M6ejnN4fU?ytgfZ*AGtYaeBO46T7_R}TPVeZ^SKwC1w+ zv-;PWXU`XsAhPY`eV;F7w|pzhwXpcx1$O7`WbOMR5xe%TT_-SS;e}mhBAx#3 zW(QT0muCr&$9$q*V-W52i-)1ua%8W5I)yc^Yzy{%ndKP|c885t*x2qA7k#YX?Dg@O z(V{xn)Y+_H=UL^Bv+|wBFWYK&nC#ASdijlIaaPR5UHt9E-YoxCxi^YGU4lW>O1ZBZ z%`7WNmaFw*y=Jcyh+KNZD*-6$TmZJ*QL1IySc1{4g2Akeu}rMPaw2P%kt`#k7N;3o zUtY_3!E~@SL0arM0YnZxbasK@DO4_OSa=w&DUN%zxtwm6N z5szh?VueBmiTrC8g-$qD{W+jVeK_lOv6f~+NiRAKos(6AWiSl-f+VWntwy7E1OS9}nSm?4w zbB`?*4^0x0|2xY=&z>p0tkzcfJ(X{kf2-UZ#h)(r0I0?F{lz&M?a3k01lGr4926)K{)KT zrEFTXSt{Swp$={sK4`O)+hee7tO5t0!biSrrErz z0;UV^Yr0wvQFU&!QQT$0k7{-PfzCzok&i;W9UdE)$Y>t<(nP2)>2iIw7I5J-fwjN= z2J#UVjd%!q^f{pm0Z0l z3dw;-!*Q4bdp=mE6$ah9{q*)kGy)O*O%?X#eU@0GL8D74su$>)>`Z|MiXtKA|;@}XgCZyT`Jd-uGhsIJym@7_1I`3#dbO2 zMCC{!2o$5A z6#2TRKkE)9k1?TMlk=&awra<<=%B~C$%!^b?QR-r%eWw$KqYc5r=!0=#=GU`mHjP~7mp0BNmnAXDqsTc!Le7T&VkAoltXV8_$UkU5 z$hZL`Hgu;JApHTzgRn6KUE8`QT1W1+kLTi@9wpY=WE~l;bSl0onXJ+ z8tuJUV;i+#FKqAbjqKZlcDVmi|KW?ZQ^Bd={5kwrOE!AC7NDD6^kQvqG#Xqyd2)Y$ zzrKIA-XHFsJag*Qsgr2lJ#z73r`@}s_u%OZ7cQKXUuz$h1%BasHa3En!(KR~Vew*c z=YBY9?gi)1)=vk=FPu5|?3ok6M!+5;bQ#I7pqg&5vEdpRwMU)s!_xru!b$yIJEO?( z;mcZs0H7G{x&G=eoRpvRsokL6dJzgoKIm)U6vO`g@I^>sz0kgGIKTo*JMB)#e&pX9 z!*K^sbKmc`T5jGXkr#&0IHj-c{b(!7uP&4pR5T8?(8)NfTjZPscV;>J9q9X=gBd}^Gpx()cVt`=KfA+!! zw2DTb4{n@!)-KPU4=z7nKkNRjp927%J%8@p+2;a`;!GXGJag{sv-px|#0};)I`v~Y zedVP~FP)kPSr1*KLbFV4)EyN^Yt?q&YU`PLBE}< zpF4xWoH-4cOFMbvIE$g5J3Tp$7f$XvQs5sikPbh5`y=1@-V6WcxBTq4gK_br%qvfq z3Z`%$NW$$Mh^Y00ZpU*PDuIpBreif11F)LfVsLxdXZGjd0J@flh@&;swush(~*!;!h zv&V2&6ZRt9+-^ke=COeu-i+|P?3Ne7;x>ZJijk^p)!ZrucO3f*uEzrr_Ly2o{y0Rk z5nHOzqd{FB?jplNd(gpf)J_I@r`0ByA`aw!dmH*z-7iq>`(=qJ!aRimgr4v3f>n>V z$@fpb3asKOORp83jKVJ7eX5By7;T7hjV-bZVGz}Vd(lR>@do5D%3`ter|u{UGM&mulo)$`DE=s-vQ#+ zf8Vn9e_Y~UM#UR3u_R>}ZOZt_iT33;f8o2=*7*4z-xRw2?1!c_)!d^A1j0;;t;`xC z`IG+R5MTb2`9l;7687b=kup+EpZV!jvp-&-S(j30h`Nhd|1g>a3x}D7@b{+r`GZCJ zamyct4P?zP*6XcQuQxt0A7~S^OZN&?!(OmCXb(b&cH!hG3?<(8@IUy0-v=D{`IH|8 zQQ}uuKMKb)(`LL`$n?A)5s~S+e{BJ{Xy(Z20JwPf2QK~C#@ZS`FZu2WfWNdvciL+% z(HP`+ub=+YKLx1sLnEyH`_gCs@}FB^p1J$K!Pffxw$3lS@kQ97_(@Op=RUGPpHTz5 zRJf@YvNyoPz2IRTb5dCnJMJgTMg7&AMLRA?!RJ%Wf9tK{&8JDI&|I#iI_oXm*+TUC zn(v(G`r9k(yfm4f^aBx||Iy+gpGTeF{DgcV zao{XJ)bs7%mp=O!KU;iOg=q1?|M&i1+6Nu-lb+fS|69eoT8spr@l)f1-T$`>^w$Z8 zqkKcV`jo0 z{;*sRX|gD^2gbq+`@8jbO3f(UU%Qi|4w&$A?YDpH_y71^Yis=6@K7Xre0kYETkXbf zuTS$waoLoI+WL>vKJ}k3GwnsB^?Sa5g5alC*?(ycbjFW`uz26!D+P;rT6VCQYjNA6Cy8If4t~Svz?bFyR;tK`_1A5nMZl`7ry-FTmSXi8b7go zMPm4`%J))$`2N&Syzz;j0O9eI)|JCAM zEk=STQhf6Be`|h!<|S5)2IIY(H26Q4X@3DCd^t6n@BR4_vq|@sC4`AR*LY{rdV9zB zPPF{l)%9MQ3{Uxy5b7WJg%WU>M~C0?o4*l0xV5&%&qd!2C;aIJx+y@2UwirU=l>;$ zke}GD!45z1_1`p?5IwdQqQt-YL!bZOzVDmX*7!+J?yK)9(br<6nBEPC?<>^du-zTjM9aWxV=rrF$trg#FJwefbTnGe7Cw@RR>Z@%{?Y;CKD>$A0fCKeD#Q zPkL%6f3|p6t02LTJ%4O2f9ZuIdS4XV4AUg|*Gn{?riukf@ZA@R&n4YiVG!d49fxmUVI1uJh;OA~^{p$Ds+S(dF88rQKrF$trfxRDn z>1Y3aP#-^O3jCMv{}YALv=9ZpbZ_sazW`m3pY+uJ`F9oXYB35-pNstc6Z891f1P3k z7|Rcoi@x=Pg}SiDT{a&qrLRz_pYakH@^V!rRC4>U%0b{s4p#l{-c$3 zUYh*UyWew97YF$~`upWC{PLGS^tE@b@sr*neyn^i1qiVI4}SFH`Mclq|K~Rs#?wL+ z*!Z@W|F3udskJqJ(o;M0hsC>Ej0Drxm@ggsSLaS`81A;=#aGZGnzqLL-(}igfC$sp znAiS9iP@xkTZjtN)|g*eUGJsIFl~+5_~sIDm`8_yces&dkKXgmYisq&zG1@y0;aO;?JzE_a#a3{l8EG4)aLykFGy^?RVj6 z#ZMYry9;zvfE4%t#q0kdpA`Sz#rMtKI6Sr%BE?VNy#IS&IELg1_@pQIcRy63uf<65 zPkJ*mwYFcmHl;(v#!ix++3Ek_Z(ca|L!bDDHGXQoJ@T!!muIy1+SN-}UcFlHwhB>M z+%O0FKmC>O%w2^vK^1B^KK*6GPybYrh7s=(KHRi0mg$hGUHQd7`lt1^HGXcUAoH0; z`mx}0GrVuOEEV}~J+?f_C4CIx zB&_qgNIPwPqGT5aUJKcu?9)J-%zhAiOcC>cdD%Wov)|Zxh;ln zG6?yV6gIu|%5q(np7D44?m6R+yqe#AChj>in?zJ%+Vb}!GnzC0o)=v;!E+2(l2K4` j7!h&hy|3kue9G?eo^K$^zlr}{dUkE?>pu2=eEa_av{Z3t literal 0 HcmV?d00001 From 74ba605c2f32fe2b8d3d229434621587cd708801 Mon Sep 17 00:00:00 2001 From: Yngrid Coello Date: Wed, 18 Jan 2023 14:51:32 +0100 Subject: [PATCH 40/44] [APM] Extracting serviceGroupApiMethods to avoid duplication of code (#149026) Closes https://github.com/elastic/kibana/issues/148280. ### Changes - Created `ApmApiClient` type. - Extracted service groups api methods to reuse in `save_service_groups` and `service_group_count` tests. --- .../test/apm_api_integration/common/config.ts | 6 +- .../service_groups/save_service_group.spec.ts | 75 +++++-------------- .../service_group_count.spec.ts | 74 ++++-------------- .../service_groups_api_methods.ts | 66 ++++++++++++++++ 4 files changed, 99 insertions(+), 122 deletions(-) create mode 100644 x-pack/test/apm_api_integration/tests/service_groups/service_groups_api_methods.ts diff --git a/x-pack/test/apm_api_integration/common/config.ts b/x-pack/test/apm_api_integration/common/config.ts index 82dd9d5b8b26f..b1991a837335c 100644 --- a/x-pack/test/apm_api_integration/common/config.ts +++ b/x-pack/test/apm_api_integration/common/config.ts @@ -58,6 +58,8 @@ type ApmApiClientKey = | 'createAndAllAgentKeysUser' | 'monitorClusterAndIndicesUser'; +export type ApmApiClient = Record>>; + export interface CreateTest { testFiles: string[]; servers: any; @@ -66,9 +68,7 @@ export interface CreateTest { apmFtrConfig: () => ApmFtrConfig; registry: ({ getService }: FtrProviderContext) => ReturnType; synthtraceEsClient: (context: InheritedFtrProviderContext) => Promise; - apmApiClient: ( - context: InheritedFtrProviderContext - ) => Record>>; + apmApiClient: (context: InheritedFtrProviderContext) => ApmApiClient; ml: ({ getService }: FtrProviderContext) => ReturnType; }; junit: { reportName: string }; diff --git a/x-pack/test/apm_api_integration/tests/service_groups/save_service_group.spec.ts b/x-pack/test/apm_api_integration/tests/service_groups/save_service_group.spec.ts index 8eeb4b43f7d30..b3dfdcdeb515a 100644 --- a/x-pack/test/apm_api_integration/tests/service_groups/save_service_group.spec.ts +++ b/x-pack/test/apm_api_integration/tests/service_groups/save_service_group.spec.ts @@ -8,85 +8,44 @@ import expect from '@kbn/expect'; import { ApmApiError } from '../../common/apm_api_supertest'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { expectToReject } from '../../common/utils/expect_to_reject'; +import { + createServiceGroupApi, + deleteAllServiceGroups, + getServiceGroupsApi, +} from './service_groups_api_methods'; export default function ApiTest({ getService }: FtrProviderContext) { const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); - async function createServiceGroupApi({ - serviceGroupId, - groupName, - kuery, - description, - color, - }: { - serviceGroupId?: string; - groupName: string; - kuery: string; - description?: string; - color?: string; - }) { - const response = await apmApiClient.writeUser({ - endpoint: 'POST /internal/apm/service-group', - params: { - query: { - serviceGroupId, - }, - body: { - groupName, - kuery, - description, - color, - }, - }, - }); - return response; - } - - async function getServiceGroupsApi() { - return apmApiClient.writeUser({ - endpoint: 'GET /internal/apm/service-groups', - }); - } - - async function deleteAllServiceGroups() { - return await getServiceGroupsApi().then((response) => { - const promises = response.body.serviceGroups.map((item) => { - if (item.id) { - return apmApiClient.writeUser({ - endpoint: 'DELETE /internal/apm/service-group', - params: { query: { serviceGroupId: item.id } }, - }); - } - }); - return Promise.all(promises); - }); - } - registry.when('Service group create', { config: 'basic', archives: [] }, () => { - afterEach(deleteAllServiceGroups); + afterEach(async () => { + await deleteAllServiceGroups(apmApiClient); + }); it('creates a new service group', async () => { const serviceGroup = { groupName: 'synthbeans', kuery: 'service.name: synth*', }; - const createResponse = await createServiceGroupApi(serviceGroup); + const createResponse = await createServiceGroupApi({ apmApiClient, ...serviceGroup }); expect(createResponse.status).to.be(200); expect(createResponse.body).to.have.property('id'); expect(createResponse.body).to.have.property('groupName', serviceGroup.groupName); expect(createResponse.body).to.have.property('kuery', serviceGroup.kuery); expect(createResponse.body).to.have.property('updatedAt'); - const serviceGroupsResponse = await getServiceGroupsApi(); + const serviceGroupsResponse = await getServiceGroupsApi(apmApiClient); expect(serviceGroupsResponse.body.serviceGroups.length).to.be(1); }); it('handles invalid fields with error response', async () => { - const err = await expectToReject(() => - createServiceGroupApi({ - groupName: 'synthbeans', - kuery: 'service.name: synth* or transaction.type: request', - }) + const err = await expectToReject( + async () => + await createServiceGroupApi({ + apmApiClient, + groupName: 'synthbeans', + kuery: 'service.name: synth* or transaction.type: request', + }) ); expect(err.res.status).to.be(400); diff --git a/x-pack/test/apm_api_integration/tests/service_groups/service_group_count/service_group_count.spec.ts b/x-pack/test/apm_api_integration/tests/service_groups/service_group_count/service_group_count.spec.ts index 3fe37df612d0d..69e3d7678ca9e 100644 --- a/x-pack/test/apm_api_integration/tests/service_groups/service_group_count/service_group_count.spec.ts +++ b/x-pack/test/apm_api_integration/tests/service_groups/service_group_count/service_group_count.spec.ts @@ -4,10 +4,15 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import expect from '@kbn/expect'; import { ApmRuleType } from '@kbn/apm-plugin/common/rules/apm_rule_types'; +import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; import { waitForActiveAlert } from '../../../common/utils/wait_for_active_alert'; +import { + createServiceGroupApi, + deleteAllServiceGroups, + getServiceGroupCounts, +} from '../service_groups_api_methods'; import { generateData } from './generate_data'; export default function ApiTest({ getService }: FtrProviderContext) { @@ -21,61 +26,6 @@ export default function ApiTest({ getService }: FtrProviderContext) { const start = Date.now() - 24 * 60 * 60 * 1000; const end = Date.now(); - async function getServiceGroupCounts() { - return apmApiClient.readUser({ - endpoint: 'GET /internal/apm/service-group/counts', - }); - } - - async function saveServiceGroup({ - serviceGroupId, - groupName, - kuery, - description, - color, - }: { - serviceGroupId?: string; - groupName: string; - kuery: string; - description?: string; - color?: string; - }) { - return apmApiClient.writeUser({ - endpoint: 'POST /internal/apm/service-group', - params: { - query: { - serviceGroupId, - }, - body: { - groupName, - kuery, - description, - color, - }, - }, - }); - } - - async function getServiceGroupsApi() { - return apmApiClient.writeUser({ - endpoint: 'GET /internal/apm/service-groups', - }); - } - - async function deleteAllServiceGroups() { - return await getServiceGroupsApi().then((response) => { - const promises = response.body.serviceGroups.map((item) => { - if (item.id) { - return apmApiClient.writeUser({ - endpoint: 'DELETE /internal/apm/service-group', - params: { query: { serviceGroupId: item.id } }, - }); - } - }); - return Promise.all(promises); - }); - } - async function createRule() { return supertest .post(`/api/alerting/rule`) @@ -107,11 +57,13 @@ export default function ApiTest({ getService }: FtrProviderContext) { const [, { body: synthbeansServiceGroup }, { body: opbeansServiceGroup }] = await Promise.all( [ generateData({ start, end, synthtraceEsClient }), - saveServiceGroup({ + createServiceGroupApi({ + apmApiClient, groupName: 'synthbeans', kuery: 'service.name: synth*', }), - saveServiceGroup({ + createServiceGroupApi({ + apmApiClient, groupName: 'opbeans', kuery: 'service.name: opbeans*', }), @@ -122,12 +74,12 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); after(async () => { - await deleteAllServiceGroups(); + await deleteAllServiceGroups(apmApiClient); await synthtraceEsClient.clean(); }); it('returns the correct number of services', async () => { - const response = await getServiceGroupCounts(); + const response = await getServiceGroupCounts(apmApiClient); expect(response.status).to.be(200); expect(Object.keys(response.body).length).to.be(2); expect(response.body[synthbeansServiceGroupId]).to.have.property('services', 2); @@ -148,7 +100,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns the correct number of alerts', async () => { - const response = await getServiceGroupCounts(); + const response = await getServiceGroupCounts(apmApiClient); expect(response.status).to.be(200); expect(Object.keys(response.body).length).to.be(2); expect(response.body[synthbeansServiceGroupId]).to.have.property('alerts', 1); diff --git a/x-pack/test/apm_api_integration/tests/service_groups/service_groups_api_methods.ts b/x-pack/test/apm_api_integration/tests/service_groups/service_groups_api_methods.ts new file mode 100644 index 0000000000000..2d0e5405cc3d1 --- /dev/null +++ b/x-pack/test/apm_api_integration/tests/service_groups/service_groups_api_methods.ts @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ApmApiClient } from '../../common/config'; + +export async function getServiceGroupsApi(apmApiClient: ApmApiClient) { + return apmApiClient.writeUser({ + endpoint: 'GET /internal/apm/service-groups', + }); +} + +export async function createServiceGroupApi({ + apmApiClient, + serviceGroupId, + groupName, + kuery, + description, + color, +}: { + apmApiClient: ApmApiClient; + serviceGroupId?: string; + groupName: string; + kuery: string; + description?: string; + color?: string; +}) { + const response = await apmApiClient.writeUser({ + endpoint: 'POST /internal/apm/service-group', + params: { + query: { + serviceGroupId, + }, + body: { + groupName, + kuery, + description, + color, + }, + }, + }); + return response; +} + +export async function getServiceGroupCounts(apmApiClient: ApmApiClient) { + return apmApiClient.readUser({ + endpoint: 'GET /internal/apm/service-group/counts', + }); +} + +export async function deleteAllServiceGroups(apmApiClient: ApmApiClient) { + return await getServiceGroupsApi(apmApiClient).then((response) => { + const promises = response.body.serviceGroups.map((item) => { + if (item.id) { + return apmApiClient.writeUser({ + endpoint: 'DELETE /internal/apm/service-group', + params: { query: { serviceGroupId: item.id } }, + }); + } + }); + return Promise.all(promises); + }); +} From 96d6b899ac75398a3f225491cf29edcf876209db Mon Sep 17 00:00:00 2001 From: Davis McPhee Date: Wed, 18 Jan 2023 09:56:43 -0400 Subject: [PATCH 41/44] [Unified Histogram] [Discover] Unified Histogram solutions cleanup (#146352) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary This PR includes a number of updates to Unified Histogram to prepare for sharing with solutions, as well as updating its usage in Discover: Unified Histogram: - Adds a `disableAutoFetching` prop, similar to Unified Field List, to disable automatic Unified Histogram refetching based on prop changes. - Accepts an `input$` observable prop that can be used to control manual refetches. - Removes `refetchId` used internally and replaces it with an observables based approach to simplify refetch logic. - Introduces a `use_stable_callback` utility hook to create callback functions with stable identities which simplifies `useCallback` logic — should be replaced with `useEvent` or whatever the React team comes up with to solve this specific issue when available: https://github.com/reactjs/rfcs/pull/220. - Eliminates debouncing logic in Unified Histogram since it was hacky — manual refetching should be used instead if debouncing is needed. - Accepts `query`, `filters`, and `timeRange` props to remove dependencies on specific services. - Updates `use_request_params` to export `getTimeRange` and `updateTimeRange` functions for easier absolute time range handling. - Exposes some Lens embeddable props to allow further customizing Unified Histogram behaviour. Discover: - Exports a `fetch$` observable from `use_saved_search` to allow listening for when data fetches should be triggered. - Uses new manual refetching support in Unified Histogram to simplify refetching logic. - Passes `query`, `filters`, and `timeRange` props to Unified Histogram. ### Checklist - [ ] ~Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)~ - [ ] ~[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials~ - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] ~Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/))~ - [ ] ~Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))~ - [ ] ~If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)~ - [ ] ~This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))~ - [ ] ~This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers)~ ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../layout/discover_histogram_layout.test.tsx | 5 +- .../layout/discover_histogram_layout.tsx | 4 + .../layout/discover_layout.test.tsx | 6 +- .../components/layout/discover_layout.tsx | 3 + .../main/components/layout/types.ts | 9 +- .../layout/use_discover_histogram.test.tsx | 110 +++++++++++++++-- .../layout/use_discover_histogram.ts | 102 +++++++++++----- .../main/discover_main_app.test.tsx | 4 + .../application/main/discover_main_app.tsx | 2 + .../main/hooks/use_discover_state.ts | 3 +- .../main/hooks/use_saved_search.ts | 77 ++++++++---- src/plugins/unified_histogram/kibana.json | 2 +- .../public/chart/chart.test.tsx | 14 +-- .../unified_histogram/public/chart/chart.tsx | 68 +++++++---- .../unified_histogram/public/chart/consts.ts | 9 -- .../public/chart/histogram.test.tsx | 66 +++-------- .../public/chart/histogram.tsx | 112 +++++++----------- .../public/chart/use_lens_props.test.ts | 93 +++++++++++++++ .../public/chart/use_lens_props.ts | 74 ++++++++++++ .../public/chart/use_refetch.test.ts | 85 +++++++++++++ .../{use_refetch_id.ts => use_refetch.ts} | 45 ++++--- .../public/chart/use_refetch_id.test.ts | 68 ----------- .../public/chart/use_request_params.test.ts | 48 ++++++++ .../public/chart/use_request_params.tsx | 57 ++++----- .../public/chart/use_stable_callback.test.ts | 19 +++ .../public/chart/use_stable_callback.ts | 23 ++++ .../public/chart/use_total_hits.test.ts | 30 ++--- .../public/chart/use_total_hits.ts | 65 +++++----- src/plugins/unified_histogram/public/index.ts | 3 + .../public/layout/layout.test.tsx | 17 +-- .../public/layout/layout.tsx | 60 +++++++++- src/plugins/unified_histogram/public/types.ts | 22 +++- src/plugins/unified_histogram/tsconfig.json | 1 - .../discover/group1/_discover_histogram.ts | 15 +++ 34 files changed, 903 insertions(+), 418 deletions(-) delete mode 100644 src/plugins/unified_histogram/public/chart/consts.ts create mode 100644 src/plugins/unified_histogram/public/chart/use_lens_props.test.ts create mode 100644 src/plugins/unified_histogram/public/chart/use_lens_props.ts create mode 100644 src/plugins/unified_histogram/public/chart/use_refetch.test.ts rename src/plugins/unified_histogram/public/chart/{use_refetch_id.ts => use_refetch.ts} (79%) delete mode 100644 src/plugins/unified_histogram/public/chart/use_refetch_id.test.ts create mode 100644 src/plugins/unified_histogram/public/chart/use_request_params.test.ts create mode 100644 src/plugins/unified_histogram/public/chart/use_stable_callback.test.ts create mode 100644 src/plugins/unified_histogram/public/chart/use_stable_callback.ts diff --git a/src/plugins/discover/public/application/main/components/layout/discover_histogram_layout.test.tsx b/src/plugins/discover/public/application/main/components/layout/discover_histogram_layout.test.tsx index 48eeaaaef4ac8..d99340da89857 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_histogram_layout.test.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_histogram_layout.test.tsx @@ -69,7 +69,9 @@ const mountComponent = ({ services.data.query.timefilter.timefilter.getAbsoluteTime = () => { return { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }; }; - + services.data.query.timefilter.timefilter.getTime = () => { + return { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }; + }; (services.data.query.queryString.getDefaultQuery as jest.Mock).mockReturnValue({ language: 'kuery', query: '', @@ -123,6 +125,7 @@ const mountComponent = ({ setExpandedDoc: jest.fn(), savedSearch, savedSearchData$, + savedSearchFetch$: new Subject(), savedSearchRefetch$: new Subject(), stateContainer, onFieldEdited: jest.fn(), diff --git a/src/plugins/discover/public/application/main/components/layout/discover_histogram_layout.tsx b/src/plugins/discover/public/application/main/components/layout/discover_histogram_layout.tsx index 7c948d8a29f60..aa4027c22aedc 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_histogram_layout.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_histogram_layout.tsx @@ -15,6 +15,7 @@ import type { DiscoverSearchSessionManager } from '../../services/discover_searc import type { InspectorAdapters } from '../../hooks/use_inspector'; import { type DiscoverMainContentProps, DiscoverMainContent } from './discover_main_content'; import { ResetSearchButton } from './reset_search_button'; +import type { DataFetch$ } from '../../hooks/use_saved_search'; export interface DiscoverHistogramLayoutProps extends DiscoverMainContentProps { resetSavedSearch: () => void; @@ -22,6 +23,7 @@ export interface DiscoverHistogramLayoutProps extends DiscoverMainContentProps { resizeRef: RefObject; inspectorAdapters: InspectorAdapters; searchSessionManager: DiscoverSearchSessionManager; + savedSearchFetch$: DataFetch$; } export const DiscoverHistogramLayout = ({ @@ -30,6 +32,7 @@ export const DiscoverHistogramLayout = ({ resetSavedSearch, savedSearch, savedSearchData$, + savedSearchFetch$, stateContainer, isTimeBased, resizeRef, @@ -51,6 +54,7 @@ export const DiscoverHistogramLayout = ({ isTimeBased, inspectorAdapters, searchSessionManager, + savedSearchFetch$, ...commonProps, }); diff --git a/src/plugins/discover/public/application/main/components/layout/discover_layout.test.tsx b/src/plugins/discover/public/application/main/components/layout/discover_layout.test.tsx index 6a9bd2d381d98..2d6998df4898f 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_layout.test.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_layout.test.tsx @@ -24,6 +24,7 @@ import { dataViewWithTimefieldMock } from '../../../../__mocks__/data_view_with_ import { AvailableFields$, DataDocuments$, + DataFetch$, DataMain$, DataRefetch$, DataTotalHits$, @@ -58,7 +59,9 @@ function mountComponent( [SIDEBAR_CLOSED_KEY]: prevSidebarClosed, }) as unknown as Storage, } as unknown as DiscoverServices; - + services.data.query.timefilter.timefilter.getTime = () => { + return { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }; + }; (services.data.query.queryString.getDefaultQuery as jest.Mock).mockReturnValue({ language: 'kuery', query: '', @@ -113,6 +116,7 @@ function mountComponent( resetSavedSearch: jest.fn(), savedSearch: savedSearchMock, savedSearchData$, + savedSearchFetch$: new Subject() as DataFetch$, savedSearchRefetch$: new Subject() as DataRefetch$, searchSource: searchSourceMock, state: { columns: [], query, hideChart: false, interval: 'auto' }, diff --git a/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx index c9f52bd548f25..f93bb7b9ff8ea 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx @@ -62,6 +62,7 @@ export function DiscoverLayout({ onChangeDataView, onUpdateQuery, setExpandedDoc, + savedSearchFetch$, savedSearchRefetch$, resetSavedSearch, savedSearchData$, @@ -237,6 +238,7 @@ export function DiscoverLayout({ setExpandedDoc={setExpandedDoc} savedSearch={savedSearch} savedSearchData$={savedSearchData$} + savedSearchFetch$={savedSearchFetch$} savedSearchRefetch$={savedSearchRefetch$} stateContainer={stateContainer} isTimeBased={isTimeBased} @@ -270,6 +272,7 @@ export function DiscoverLayout({ resultState, savedSearch, savedSearchData$, + savedSearchFetch$, savedSearchRefetch$, searchSessionManager, setExpandedDoc, diff --git a/src/plugins/discover/public/application/main/components/layout/types.ts b/src/plugins/discover/public/application/main/components/layout/types.ts index f2a8ebe9269e8..34b8650ffc153 100644 --- a/src/plugins/discover/public/application/main/components/layout/types.ts +++ b/src/plugins/discover/public/application/main/components/layout/types.ts @@ -9,10 +9,10 @@ import type { Query, TimeRange, AggregateQuery } from '@kbn/es-query'; import type { DataView } from '@kbn/data-views-plugin/public'; import type { ISearchSource } from '@kbn/data-plugin/public'; -import { SavedSearch } from '@kbn/saved-search-plugin/public'; -import { DataTableRecord } from '../../../../types'; -import { DiscoverStateContainer } from '../../services/discover_state'; -import { DataRefetch$, SavedSearchData } from '../../hooks/use_saved_search'; +import type { SavedSearch } from '@kbn/saved-search-plugin/public'; +import type { DataTableRecord } from '../../../../types'; +import type { DiscoverStateContainer } from '../../services/discover_state'; +import type { DataFetch$, DataRefetch$, SavedSearchData } from '../../hooks/use_saved_search'; import type { DiscoverSearchSessionManager } from '../../services/discover_search_session'; import type { InspectorAdapters } from '../../hooks/use_inspector'; @@ -29,6 +29,7 @@ export interface DiscoverLayoutProps { setExpandedDoc: (doc?: DataTableRecord) => void; savedSearch: SavedSearch; savedSearchData$: SavedSearchData; + savedSearchFetch$: DataFetch$; savedSearchRefetch$: DataRefetch$; searchSource: ISearchSource; stateContainer: DiscoverStateContainer; diff --git a/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.test.tsx b/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.test.tsx index 950b2d4571a40..89059db91e7f5 100644 --- a/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.test.tsx +++ b/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.test.tsx @@ -9,11 +9,12 @@ import React, { ReactElement } from 'react'; import { buildDataTableRecord } from '../../../../utils/build_data_record'; import { esHits } from '../../../../__mocks__/es_hits'; import { act, renderHook, WrapperComponent } from '@testing-library/react-hooks'; -import { BehaviorSubject } from 'rxjs'; +import { BehaviorSubject, Subject } from 'rxjs'; import { FetchStatus } from '../../../types'; import { AvailableFields$, DataDocuments$, + DataFetch$, DataMain$, DataTotalHits$, RecordRawType, @@ -72,6 +73,15 @@ jest.mock('@kbn/unified-field-list-plugin/public', () => { return { ...originalModule, getVisualizeInformation: jest.fn(() => Promise.resolve(mockCanVisualize)), + useQuerySubscriber: jest.fn(() => ({ + query: { + query: 'query', + language: 'kuery', + }, + filters: [], + fromDate: 'now-15m', + toDate: 'now', + })), }; }); @@ -120,6 +130,7 @@ describe('useDiscoverHistogram', () => { recordRawType: isPlainRecord ? RecordRawType.PLAIN : RecordRawType.DOCUMENT, foundDocuments: true, }) as DataMain$, + savedSearchFetch$ = new Subject() as DataFetch$, }: { isPlainRecord?: boolean; isTimeBased?: boolean; @@ -131,6 +142,7 @@ describe('useDiscoverHistogram', () => { inspectorAdapters?: InspectorAdapters; totalHits$?: DataTotalHits$; main$?: DataMain$; + savedSearchFetch$?: DataFetch$; } = {}) => { mockStorage = storage; mockCanVisualize = canVisualize; @@ -161,6 +173,7 @@ describe('useDiscoverHistogram', () => { const initialProps = { stateContainer, savedSearchData$, + savedSearchFetch$, dataView: dataViewWithTimefieldMock, savedSearch: savedSearchMock, isTimeBased, @@ -188,11 +201,20 @@ describe('useDiscoverHistogram', () => { return { hook, initialProps }; }; - it('should return undefined if there is no search session', async () => { - const { - hook: { result }, - } = await renderUseDiscoverHistogram({ searchSessionId: null }); - expect(result.current).toBeUndefined(); + describe('result', () => { + it('should return undefined if there is no search session', async () => { + const { + hook: { result }, + } = await renderUseDiscoverHistogram({ searchSessionId: null }); + expect(result.current).toBeUndefined(); + }); + + it('it should not return undefined if there is no search session, but isPlainRecord is true', async () => { + const { + hook: { result }, + } = await renderUseDiscoverHistogram({ searchSessionId: null, isPlainRecord: true }); + expect(result.current).toBeDefined(); + }); }); describe('contexts', () => { @@ -263,6 +285,21 @@ describe('useDiscoverHistogram', () => { }); }); + describe('search params', () => { + it('should return the correct query, filters, and timeRange', async () => { + const { hook } = await renderUseDiscoverHistogram(); + expect(hook.result.current?.query).toEqual({ + query: 'query', + language: 'kuery', + }); + expect(hook.result.current?.filters).toEqual([]); + expect(hook.result.current?.timeRange).toEqual({ + from: 'now-15m', + to: 'now', + }); + }); + }); + describe('onEditVisualization', () => { it('returns a callback for onEditVisualization when the data view can be visualized', async () => { const { @@ -364,7 +401,7 @@ describe('useDiscoverHistogram', () => { } = await renderUseDiscoverHistogram({ inspectorAdapters }); expect(inspectorAdapters.lensRequests).toBeUndefined(); act(() => { - result.current?.onChartLoad({ complete: true, adapters: { requests: lensRequests } }); + result.current?.onChartLoad({ adapters: { requests: lensRequests } }); }); expect(inspectorAdapters.lensRequests).toBeDefined(); }); @@ -486,4 +523,63 @@ describe('useDiscoverHistogram', () => { expect(mockCheckHitCount).not.toHaveBeenCalled(); }); }); + + describe('refetching', () => { + it("should call input$.next({ type: 'refetch' }) when savedSearchFetch$ is triggered", async () => { + const savedSearchFetch$ = new BehaviorSubject({ reset: false, searchSessionId: '1234' }); + const { hook } = await renderUseDiscoverHistogram({ savedSearchFetch$ }); + const onRefetch = jest.fn(); + hook.result.current?.input$.subscribe(onRefetch); + act(() => { + savedSearchFetch$.next({ reset: false, searchSessionId: '1234' }); + }); + expect(onRefetch).toHaveBeenCalledWith({ type: 'refetch' }); + }); + + it("should not call input$.next({ type: 'refetch' }) when searchSessionId is not set", async () => { + const savedSearchFetch$ = new BehaviorSubject({ reset: false, searchSessionId: '1234' }); + const { hook } = await renderUseDiscoverHistogram({ + savedSearchFetch$, + searchSessionId: null, + }); + const onRefetch = jest.fn(); + hook.result.current?.input$.subscribe(onRefetch); + act(() => { + savedSearchFetch$.next({ reset: false, searchSessionId: '1234' }); + }); + expect(onRefetch).not.toHaveBeenCalled(); + }); + + it("should call input$.next({ type: 'refetch' }) when searchSessionId is not set and isPlainRecord is true", async () => { + const savedSearchFetch$ = new BehaviorSubject({ reset: false, searchSessionId: '1234' }); + const { hook } = await renderUseDiscoverHistogram({ + savedSearchFetch$, + searchSessionId: null, + isPlainRecord: true, + }); + const onRefetch = jest.fn(); + hook.result.current?.input$.subscribe(onRefetch); + act(() => { + savedSearchFetch$.next({ reset: false, searchSessionId: '1234' }); + }); + expect(onRefetch).toHaveBeenCalledWith({ type: 'refetch' }); + }); + + it('should skip the next refetch when state.hideChart changes from true to false', async () => { + const savedSearchFetch$ = new BehaviorSubject({ reset: false, searchSessionId: '1234' }); + const { hook } = await renderUseDiscoverHistogram({ savedSearchFetch$ }); + const onRefetch = jest.fn(); + hook.result.current?.input$.subscribe(onRefetch); + act(() => { + hook.result.current?.onChartHiddenChange(true); + }); + act(() => { + hook.result.current?.onChartHiddenChange(false); + }); + act(() => { + savedSearchFetch$.next({ reset: false, searchSessionId: '1234' }); + }); + expect(onRefetch).not.toHaveBeenCalled(); + }); + }); }); diff --git a/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts b/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts index 53ddc74ad99d6..d380244fe875b 100644 --- a/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts +++ b/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts @@ -8,20 +8,22 @@ import type { DataView, DataViewField } from '@kbn/data-views-plugin/common'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; -import { getVisualizeInformation } from '@kbn/unified-field-list-plugin/public'; -import { useCallback, useEffect, useMemo, useState } from 'react'; +import { getVisualizeInformation, useQuerySubscriber } from '@kbn/unified-field-list-plugin/public'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { UnifiedHistogramFetchStatus, UnifiedHistogramHitsContext, + UnifiedHistogramInputMessage, } from '@kbn/unified-histogram-plugin/public'; import type { UnifiedHistogramChartLoadEvent } from '@kbn/unified-histogram-plugin/public'; import useObservable from 'react-use/lib/useObservable'; import type { TypedLensByValueInput } from '@kbn/lens-plugin/public'; +import { Subject } from 'rxjs'; import { useAppStateSelector } from '../../services/discover_app_state_container'; import { getUiActions } from '../../../../kibana_services'; import { useDiscoverServices } from '../../../../hooks/use_discover_services'; import { useDataState } from '../../hooks/use_data_state'; -import type { SavedSearchData } from '../../hooks/use_saved_search'; +import type { DataFetch$, SavedSearchData } from '../../hooks/use_saved_search'; import type { DiscoverStateContainer } from '../../services/discover_state'; import { FetchStatus } from '../../../types'; import type { DiscoverSearchSessionManager } from '../../services/discover_search_session'; @@ -41,6 +43,7 @@ export interface UseDiscoverHistogramProps { isPlainRecord: boolean; inspectorAdapters: InspectorAdapters; searchSessionManager: DiscoverSearchSessionManager; + savedSearchFetch$: DataFetch$; } export const useDiscoverHistogram = ({ @@ -52,6 +55,7 @@ export const useDiscoverHistogram = ({ isPlainRecord, inspectorAdapters, searchSessionManager, + savedSearchFetch$, }: UseDiscoverHistogramProps) => { const { storage, data, lens } = useDiscoverServices(); const [hideChart, interval, breakdownField] = useAppStateSelector((state) => [ @@ -124,21 +128,6 @@ export const useDiscoverHistogram = ({ [stateContainer] ); - /** - * Request - */ - - // The searchSessionId will be updated whenever a new search - // is started and will trigger a unified histogram refetch - const searchSessionId = useObservable(searchSessionManager.searchSessionId$); - const request = useMemo( - () => ({ - searchSessionId, - adapter: inspectorAdapters.requests, - }), - [inspectorAdapters.requests, searchSessionId] - ); - /** * Total hits */ @@ -216,32 +205,23 @@ export const useDiscoverHistogram = ({ [inspectorAdapters] ); - const [chartHidden, setChartHidden] = useState(hideChart); const chart = useMemo( () => isPlainRecord || !isTimeBased ? undefined : { - hidden: chartHidden, + hidden: hideChart, timeInterval: interval, }, - [chartHidden, interval, isPlainRecord, isTimeBased] + [hideChart, interval, isPlainRecord, isTimeBased] ); // Clear the Lens request adapter when the chart is hidden useEffect(() => { - if (chartHidden || !chart) { + if (hideChart || !chart) { inspectorAdapters.lensRequests = undefined; } - }, [chart, chartHidden, inspectorAdapters]); - - // state.chartHidden is updated before searchSessionId, which can trigger duplicate - // requests, so instead of using state.chartHidden directly, we update chartHidden - // when searchSessionId changes - useEffect(() => { - setChartHidden(hideChart); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [searchSessionId]); + }, [chart, hideChart, inspectorAdapters]); /** * Breakdown @@ -264,18 +244,78 @@ export const useDiscoverHistogram = ({ [field, isPlainRecord, isTimeBased] ); + /** + * Search params + */ + + const { query, filters, fromDate: from, toDate: to } = useQuerySubscriber({ data }); + const timeRange = useMemo( + () => (from && to ? { from, to } : data.query.timefilter.timefilter.getTimeDefaults()), + [data.query.timefilter.timefilter, from, to] + ); + + /** + * Request + */ + + // The searchSessionId will be updated whenever a new search is started + const searchSessionId = useObservable(searchSessionManager.searchSessionId$); + const request = useMemo( + () => ({ + searchSessionId, + adapter: inspectorAdapters.requests, + }), + [inspectorAdapters.requests, searchSessionId] + ); + + /** + * Data fetching + */ + + const input$ = useMemo(() => new Subject(), []); + // Initialized when the first search has been requested or // when in SQL mode since search sessions are not supported const isInitialized = Boolean(searchSessionId) || isPlainRecord; + const skipRefetch = useRef(); + + // Skip refetching when showing the chart since Lens will + // automatically fetch when the chart is shown + useEffect(() => { + if (skipRefetch.current === undefined) { + skipRefetch.current = false; + } else { + skipRefetch.current = !hideChart; + } + }, [hideChart]); + + // Trigger a unified histogram refetch when savedSearchFetch$ is triggered + useEffect(() => { + const subscription = savedSearchFetch$.subscribe(() => { + if (isInitialized && !skipRefetch.current) { + input$.next({ type: 'refetch' }); + } + skipRefetch.current = false; + }); + + return () => { + subscription.unsubscribe(); + }; + }, [input$, isInitialized, savedSearchFetch$]); // Don't render the unified histogram layout until initialized return isInitialized ? { + query, + filters, + timeRange, topPanelHeight, request, hits, chart, breakdown, + disableAutoFetching: true, + input$, onEditVisualization: canVisualize ? onEditVisualization : undefined, onTopPanelHeightChange, onChartHiddenChange, diff --git a/src/plugins/discover/public/application/main/discover_main_app.test.tsx b/src/plugins/discover/public/application/main/discover_main_app.test.tsx index 7ea5e944cc6a7..f3cc7f9cee43d 100644 --- a/src/plugins/discover/public/application/main/discover_main_app.test.tsx +++ b/src/plugins/discover/public/application/main/discover_main_app.test.tsx @@ -25,6 +25,10 @@ import { DiscoverMainProvider } from './services/discover_state_provider'; setHeaderActionMenuMounter(jest.fn()); setUrlTracker(urlTrackerMock); +discoverServiceMock.data.query.timefilter.timefilter.getTime = () => { + return { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }; +}; + describe('DiscoverMainApp', () => { test('renders', async () => { const dataViewList = [dataViewMock].map((ip) => { diff --git a/src/plugins/discover/public/application/main/discover_main_app.tsx b/src/plugins/discover/public/application/main/discover_main_app.tsx index a91ed42a55a62..92f155f57bafc 100644 --- a/src/plugins/discover/public/application/main/discover_main_app.tsx +++ b/src/plugins/discover/public/application/main/discover_main_app.tsx @@ -55,6 +55,7 @@ export function DiscoverMainApp(props: DiscoverMainProps) { onUpdateQuery, persistDataView, updateAdHocDataViewId, + fetch$, refetch$, resetSavedSearch, searchSource, @@ -118,6 +119,7 @@ export function DiscoverMainApp(props: DiscoverMainProps) { navigateTo={navigateTo} savedSearch={savedSearch} savedSearchData$={data$} + savedSearchFetch$={fetch$} savedSearchRefetch$={refetch$} searchSource={searchSource} stateContainer={stateContainer} diff --git a/src/plugins/discover/public/application/main/hooks/use_discover_state.ts b/src/plugins/discover/public/application/main/hooks/use_discover_state.ts index 6eefb25580969..a8ff93ef94547 100644 --- a/src/plugins/discover/public/application/main/hooks/use_discover_state.ts +++ b/src/plugins/discover/public/application/main/hooks/use_discover_state.ts @@ -121,7 +121,7 @@ export function useDiscoverState({ /** * Data fetching logic */ - const { data$, refetch$, reset, inspectorAdapters } = useSavedSearchData({ + const { data$, fetch$, refetch$, reset, inspectorAdapters } = useSavedSearchData({ initialFetchStatus, searchSessionManager, savedSearch, @@ -322,6 +322,7 @@ export function useDiscoverState({ return { data$, inspectorAdapters, + fetch$, refetch$, resetSavedSearch, onChangeDataView, diff --git a/src/plugins/discover/public/application/main/hooks/use_saved_search.ts b/src/plugins/discover/public/application/main/hooks/use_saved_search.ts index 7f7e4700925a6..1b1a917740d43 100644 --- a/src/plugins/discover/public/application/main/hooks/use_saved_search.ts +++ b/src/plugins/discover/public/application/main/hooks/use_saved_search.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ import { useCallback, useEffect, useMemo, useRef } from 'react'; -import { BehaviorSubject, Subject } from 'rxjs'; +import { BehaviorSubject, filter, map, Observable, share, Subject, tap } from 'rxjs'; import type { AutoRefreshDoneFn } from '@kbn/data-plugin/public'; import { ISearchSource } from '@kbn/data-plugin/public'; import { RequestAdapter } from '@kbn/inspector-plugin/public'; @@ -38,7 +38,10 @@ export type DataMain$ = BehaviorSubject; export type DataDocuments$ = BehaviorSubject; export type DataTotalHits$ = BehaviorSubject; export type AvailableFields$ = BehaviorSubject; - +export type DataFetch$ = Observable<{ + reset: boolean; + searchSessionId: string; +}>; export type DataRefetch$ = Subject; export interface UseSavedSearch { @@ -151,46 +154,70 @@ export const useSavedSearch = ({ }>({}); /** - * This part takes care of triggering the data fetching by creating and subscribing - * to an observable of various possible changes in state + * handler emitted by `timefilter.getAutoRefreshFetch$()` + * to notify when data completed loading and to start a new autorefresh loop */ - useEffect(() => { - /** - * handler emitted by `timefilter.getAutoRefreshFetch$()` - * to notify when data completed loading and to start a new autorefresh loop - */ - const setAutoRefreshDone = (fn: AutoRefreshDoneFn | undefined) => { - refs.current.autoRefreshDone = fn; - }; - const fetch$ = getFetch$({ - setAutoRefreshDone, + const setAutoRefreshDone = useCallback((fn: AutoRefreshDoneFn | undefined) => { + refs.current.autoRefreshDone = fn; + }, []); + + /** + * Observable that allows listening for when fetches are triggered + */ + const fetch$ = useMemo( + () => + getFetch$({ + setAutoRefreshDone, + data, + main$, + refetch$, + searchSessionManager, + searchSource, + initialFetchStatus, + }).pipe( + filter(() => validateTimeRange(timefilter.getTime(), services.toastNotifications)), + tap(() => inspectorAdapters.requests.reset()), + map((val) => ({ + reset: val === 'reset', + searchSessionId: searchSessionManager.getNextSearchSessionId(), + })), + share() + ), + [ data, + initialFetchStatus, + inspectorAdapters.requests, main$, refetch$, searchSessionManager, searchSource, - initialFetchStatus, - }); - let abortController: AbortController; + services.toastNotifications, + setAutoRefreshDone, + timefilter, + ] + ); - const subscription = fetch$.subscribe(async (val) => { - if (!validateTimeRange(timefilter.getTime(), services.toastNotifications)) { - return; - } - inspectorAdapters.requests.reset(); + /** + * This part takes care of triggering the data fetching by creating and subscribing + * to an observable of various possible changes in state + */ + useEffect(() => { + let abortController: AbortController; + const subscription = fetch$.subscribe(async ({ reset, searchSessionId }) => { abortController?.abort(); abortController = new AbortController(); + const autoRefreshDone = refs.current.autoRefreshDone; - await fetchAll(dataSubjects, searchSource, val === 'reset', { + await fetchAll(dataSubjects, searchSource, reset, { abortController, appStateContainer: stateContainer.appState, data, initialFetchStatus, inspectorAdapters, savedSearch, - searchSessionId: searchSessionManager.getNextSearchSessionId(), + searchSessionId, services, useNewFieldsApi, }); @@ -213,6 +240,7 @@ export const useSavedSearch = ({ data, data.query.queryString, dataSubjects, + fetch$, filterManager, initialFetchStatus, inspectorAdapters, @@ -235,6 +263,7 @@ export const useSavedSearch = ({ ); return { + fetch$, refetch$, data$: dataSubjects, reset, diff --git a/src/plugins/unified_histogram/kibana.json b/src/plugins/unified_histogram/kibana.json index 5be043637ed33..aa9e22fab2a08 100755 --- a/src/plugins/unified_histogram/kibana.json +++ b/src/plugins/unified_histogram/kibana.json @@ -11,5 +11,5 @@ "ui": true, "requiredPlugins": [], "optionalPlugins": [], - "requiredBundles": ["data", "dataViews", "embeddable", "kibanaUtils", "inspector"] + "requiredBundles": ["data", "dataViews", "embeddable", "inspector"] } diff --git a/src/plugins/unified_histogram/public/chart/chart.test.tsx b/src/plugins/unified_histogram/public/chart/chart.test.tsx index 21682cb919d3c..bc4115590b4e2 100644 --- a/src/plugins/unified_histogram/public/chart/chart.test.tsx +++ b/src/plugins/unified_histogram/public/chart/chart.test.tsx @@ -39,20 +39,18 @@ async function mountComponent({ dataView?: DataView; onEditVisualization?: null | (() => void); } = {}) { - const services = unifiedHistogramServicesMock; - services.data.query.timefilter.timefilter.getAbsoluteTime = () => { - return { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }; - }; - (services.data.query.queryString.getDefaultQuery as jest.Mock).mockReturnValue({ - language: 'kuery', - query: '', - }); (searchSourceInstanceMock.fetch$ as jest.Mock).mockImplementation( jest.fn().mockReturnValue(of({ rawResponse: { hits: { total: noHits ? 0 : 2 } } })) ); const props = { dataView, + query: { + language: 'kuery', + query: '', + }, + filters: [], + timeRange: { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }, services: unifiedHistogramServicesMock, hits: noHits ? undefined diff --git a/src/plugins/unified_histogram/public/chart/chart.tsx b/src/plugins/unified_histogram/public/chart/chart.tsx index b1970cd26e365..ccfadcaa07e97 100644 --- a/src/plugins/unified_histogram/public/chart/chart.tsx +++ b/src/plugins/unified_histogram/public/chart/chart.tsx @@ -18,7 +18,9 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { DataView, DataViewField, DataViewType } from '@kbn/data-views-plugin/public'; -import type { TypedLensByValueInput } from '@kbn/lens-plugin/public'; +import type { LensEmbeddableInput, TypedLensByValueInput } from '@kbn/lens-plugin/public'; +import type { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query'; +import { Subject } from 'rxjs'; import { HitsCounter } from '../hits_counter'; import { Histogram } from './histogram'; import { useChartPanels } from './use_chart_panels'; @@ -30,26 +32,34 @@ import type { UnifiedHistogramChartLoadEvent, UnifiedHistogramRequestContext, UnifiedHistogramServices, + UnifiedHistogramInput$, + UnifiedHistogramInputMessage, } from '../types'; import { BreakdownFieldSelector } from './breakdown_field_selector'; import { useTotalHits } from './use_total_hits'; import { useRequestParams } from './use_request_params'; import { useChartStyles } from './use_chart_styles'; import { useChartActions } from './use_chart_actions'; -import { useRefetchId } from './use_refetch_id'; import { getLensAttributes } from './get_lens_attributes'; +import { useRefetch } from './use_refetch'; export interface ChartProps { className?: string; services: UnifiedHistogramServices; dataView: DataView; - lastReloadRequestTime?: number; + query?: Query | AggregateQuery; + filters?: Filter[]; + timeRange?: TimeRange; request?: UnifiedHistogramRequestContext; hits?: UnifiedHistogramHitsContext; chart?: UnifiedHistogramChartContext; breakdown?: UnifiedHistogramBreakdownContext; appendHitsCounter?: ReactElement; appendHistogram?: ReactElement; + disableAutoFetching?: boolean; + disableTriggers?: LensEmbeddableInput['disableTriggers']; + disabledActions?: LensEmbeddableInput['disabledActions']; + input$?: UnifiedHistogramInput$; onEditVisualization?: (lensAttributes: TypedLensByValueInput['attributes']) => void; onResetChartHeight?: () => void; onChartHiddenChange?: (chartHidden: boolean) => void; @@ -57,6 +67,8 @@ export interface ChartProps { onBreakdownFieldChange?: (breakdownField: DataViewField | undefined) => void; onTotalHitsChange?: (status: UnifiedHistogramFetchStatus, result?: number | Error) => void; onChartLoad?: (event: UnifiedHistogramChartLoadEvent) => void; + onFilter?: LensEmbeddableInput['onFilter']; + onBrushEnd?: LensEmbeddableInput['onBrushEnd']; } const HistogramMemoized = memo(Histogram); @@ -65,13 +77,19 @@ export function Chart({ className, services, dataView, - lastReloadRequestTime, + query: originalQuery, + filters: originalFilters, + timeRange: originalTimeRange, request, hits, chart, breakdown, appendHitsCounter, appendHistogram, + disableAutoFetching, + disableTriggers, + disabledActions, + input$: originalInput$, onEditVisualization: originalOnEditVisualization, onResetChartHeight, onChartHiddenChange, @@ -79,6 +97,8 @@ export function Chart({ onBreakdownFieldChange, onTotalHitsChange, onChartLoad, + onFilter, + onBrushEnd, }: ChartProps) { const { showChartOptionsPopover, @@ -107,15 +127,20 @@ export function Chart({ dataView.isTimeBased() ); - const { filters, query, relativeTimeRange } = useRequestParams({ + const input$ = useMemo( + () => originalInput$ ?? new Subject(), + [originalInput$] + ); + + const { filters, query, getTimeRange, updateTimeRange, relativeTimeRange } = useRequestParams({ services, - lastReloadRequestTime, - request, + query: originalQuery, + filters: originalFilters, + timeRange: originalTimeRange, }); - const refetchId = useRefetchId({ + const refetch$ = useRefetch({ dataView, - lastReloadRequestTime, request, hits, chart, @@ -124,28 +149,21 @@ export function Chart({ filters, query, relativeTimeRange, + disableAutoFetching, + input$, + beforeRefetch: updateTimeRange, }); - // We need to update the absolute time range whenever the refetchId changes - const timeRange = useMemo( - () => services.data.query.timefilter.timefilter.getAbsoluteTime(), - // eslint-disable-next-line react-hooks/exhaustive-deps - [services.data.query.timefilter.timefilter, refetchId] - ); - useTotalHits({ services, dataView, - lastReloadRequestTime, request, hits, - chart, chartVisible, - breakdown, filters, query, - timeRange, - refetchId, + getTimeRange, + refetch$, onTotalHitsChange, }); @@ -288,14 +306,18 @@ export function Chart({ {appendHistogram} diff --git a/src/plugins/unified_histogram/public/chart/consts.ts b/src/plugins/unified_histogram/public/chart/consts.ts deleted file mode 100644 index d2af2ed4ee33a..0000000000000 --- a/src/plugins/unified_histogram/public/chart/consts.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 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. - */ - -export const REQUEST_DEBOUNCE_MS = 100; diff --git a/src/plugins/unified_histogram/public/chart/histogram.test.tsx b/src/plugins/unified_histogram/public/chart/histogram.test.tsx index 03652a63f5456..7385f20358be3 100644 --- a/src/plugins/unified_histogram/public/chart/histogram.test.tsx +++ b/src/plugins/unified_histogram/public/chart/histogram.test.tsx @@ -6,18 +6,19 @@ * Side Public License, v 1. */ import { mountWithIntl } from '@kbn/test-jest-helpers'; -import { getLensProps, Histogram } from './histogram'; +import { Histogram } from './histogram'; import React from 'react'; import { unifiedHistogramServicesMock } from '../__mocks__/services'; import { dataViewWithTimefieldMock } from '../__mocks__/data_view_with_timefield'; import { createDefaultInspectorAdapters } from '@kbn/expressions-plugin/common'; -import { UnifiedHistogramFetchStatus } from '../types'; +import { UnifiedHistogramFetchStatus, UnifiedHistogramInput$ } from '../types'; import { getLensAttributes } from './get_lens_attributes'; -import { REQUEST_DEBOUNCE_MS } from './consts'; import { act } from 'react-dom/test-utils'; import * as buildBucketInterval from './build_bucket_interval'; import * as useTimeRange from './use_time_range'; import { RequestStatus } from '@kbn/inspector-plugin/public'; +import { Subject } from 'rxjs'; +import { getLensProps } from './use_lens_props'; const mockBucketInterval = { description: '1 minute', scale: undefined, scaled: false }; jest.spyOn(buildBucketInterval, 'buildBucketInterval').mockReturnValue(mockBucketInterval); @@ -43,7 +44,7 @@ function mountComponent() { }; const timefilterUpdateHandler = jest.fn(); - + const refetch$: UnifiedHistogramInput$ = new Subject(); const props = { services: unifiedHistogramServicesMock, request: { @@ -59,11 +60,11 @@ function mountComponent() { }, timefilterUpdateHandler, dataView: dataViewWithTimefieldMock, - timeRange: { + getTimeRange: () => ({ from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590', - }, - lastReloadRequestTime: 42, + }), + refetch$, lensAttributes: getMockLensAttributes(), onTotalHitsChange: jest.fn(), onChartLoad: jest.fn(), @@ -81,28 +82,27 @@ describe('Histogram', () => { expect(component.find('[data-test-subj="unifiedHistogramChart"]').exists()).toBe(true); }); - it('should render lens.EmbeddableComponent with debounced props', async () => { + it('should only update lens.EmbeddableComponent props when refetch$ is triggered', async () => { const { component, props } = mountComponent(); const embeddable = unifiedHistogramServicesMock.lens.EmbeddableComponent; expect(component.find(embeddable).exists()).toBe(true); let lensProps = component.find(embeddable).props(); const originalProps = getLensProps({ - timeRange: props.timeRange, + searchSessionId: props.request.searchSessionId, + getTimeRange: props.getTimeRange, attributes: getMockLensAttributes(), - request: props.request, - lastReloadRequestTime: props.lastReloadRequestTime, onLoad: lensProps.onLoad, }); expect(lensProps).toEqual(originalProps); - component.setProps({ lastReloadRequestTime: 43 }).update(); + component.setProps({ request: { ...props.request, searchSessionId: '321' } }).update(); lensProps = component.find(embeddable).props(); expect(lensProps).toEqual(originalProps); await act(async () => { - await new Promise((resolve) => setTimeout(resolve, REQUEST_DEBOUNCE_MS)); + props.refetch$.next({ type: 'refetch' }); }); component.update(); lensProps = component.find(embeddable).props(); - expect(lensProps).toEqual({ ...originalProps, lastReloadRequestTime: 43 }); + expect(lensProps).toEqual({ ...originalProps, searchSessionId: '321' }); }); it('should execute onLoad correctly', async () => { @@ -165,7 +165,7 @@ describe('Histogram', () => { UnifiedHistogramFetchStatus.loading, undefined ); - expect(props.onChartLoad).toHaveBeenLastCalledWith({ complete: false, adapters: {} }); + expect(props.onChartLoad).toHaveBeenLastCalledWith({ adapters: {} }); expect(buildBucketInterval.buildBucketInterval).not.toHaveBeenCalled(); expect(useTimeRange.useTimeRange).toHaveBeenLastCalledWith( expect.objectContaining({ bucketInterval: undefined }) @@ -177,7 +177,7 @@ describe('Histogram', () => { UnifiedHistogramFetchStatus.complete, 100 ); - expect(props.onChartLoad).toHaveBeenLastCalledWith({ complete: true, adapters }); + expect(props.onChartLoad).toHaveBeenLastCalledWith({ adapters }); expect(buildBucketInterval.buildBucketInterval).toHaveBeenCalled(); expect(useTimeRange.useTimeRange).toHaveBeenLastCalledWith( expect.objectContaining({ bucketInterval: mockBucketInterval }) @@ -197,7 +197,7 @@ describe('Histogram', () => { UnifiedHistogramFetchStatus.error, undefined ); - expect(props.onChartLoad).toHaveBeenLastCalledWith({ complete: false, adapters }); + expect(props.onChartLoad).toHaveBeenLastCalledWith({ adapters }); }); it('should execute onLoad correctly when the response has shard failures', async () => { @@ -222,36 +222,6 @@ describe('Histogram', () => { UnifiedHistogramFetchStatus.error, undefined ); - expect(props.onChartLoad).toHaveBeenLastCalledWith({ complete: false, adapters }); - }); - - it('should not recreate onLoad in debounced lens props when hits.total changes', async () => { - const { component, props } = mountComponent(); - const embeddable = unifiedHistogramServicesMock.lens.EmbeddableComponent; - const onLoad = component.find(embeddable).props().onLoad; - onLoad(true, undefined); - expect(props.onTotalHitsChange).toHaveBeenLastCalledWith( - UnifiedHistogramFetchStatus.loading, - undefined - ); - component - .setProps({ - hits: { - status: UnifiedHistogramFetchStatus.complete, - total: 100, - }, - }) - .update(); - expect(component.find(embeddable).props().onLoad).toBe(onLoad); - await act(async () => { - await new Promise((resolve) => setTimeout(resolve, REQUEST_DEBOUNCE_MS)); - }); - component.update(); - expect(component.find(embeddable).props().onLoad).toBe(onLoad); - onLoad(true, undefined); - expect(props.onTotalHitsChange).toHaveBeenLastCalledWith( - UnifiedHistogramFetchStatus.loading, - 100 - ); + expect(props.onChartLoad).toHaveBeenLastCalledWith({ adapters }); }); }); diff --git a/src/plugins/unified_histogram/public/chart/histogram.tsx b/src/plugins/unified_histogram/public/chart/histogram.tsx index c30c6a1410985..01caba4ad48ad 100644 --- a/src/plugins/unified_histogram/public/chart/histogram.tsx +++ b/src/plugins/unified_histogram/public/chart/histogram.tsx @@ -8,16 +8,15 @@ import { useEuiTheme } from '@elastic/eui'; import { css } from '@emotion/react'; -import React, { useCallback, useEffect, useRef, useState } from 'react'; +import React, { useState } from 'react'; import type { DataView } from '@kbn/data-views-plugin/public'; import type { DefaultInspectorAdapters } from '@kbn/expressions-plugin/common'; import type { IKibanaSearchResponse } from '@kbn/data-plugin/public'; import type { estypes } from '@elastic/elasticsearch'; import type { TimeRange } from '@kbn/es-query'; -import useDebounce from 'react-use/lib/useDebounce'; -import { ViewMode } from '@kbn/embeddable-plugin/public'; -import type { TypedLensByValueInput } from '@kbn/lens-plugin/public'; +import type { LensEmbeddableInput, TypedLensByValueInput } from '@kbn/lens-plugin/public'; import { RequestStatus } from '@kbn/inspector-plugin/public'; +import type { Observable } from 'rxjs'; import { UnifiedHistogramBucketInterval, UnifiedHistogramChartContext, @@ -26,53 +25,55 @@ import { UnifiedHistogramChartLoadEvent, UnifiedHistogramRequestContext, UnifiedHistogramServices, + UnifiedHistogramInputMessage, } from '../types'; import { buildBucketInterval } from './build_bucket_interval'; import { useTimeRange } from './use_time_range'; -import { REQUEST_DEBOUNCE_MS } from './consts'; +import { useStableCallback } from './use_stable_callback'; +import { useLensProps } from './use_lens_props'; export interface HistogramProps { services: UnifiedHistogramServices; dataView: DataView; - lastReloadRequestTime: number | undefined; request?: UnifiedHistogramRequestContext; hits?: UnifiedHistogramHitsContext; chart: UnifiedHistogramChartContext; - timeRange: TimeRange; + getTimeRange: () => TimeRange; + refetch$: Observable; lensAttributes: TypedLensByValueInput['attributes']; + disableTriggers?: LensEmbeddableInput['disableTriggers']; + disabledActions?: LensEmbeddableInput['disabledActions']; onTotalHitsChange?: (status: UnifiedHistogramFetchStatus, result?: number | Error) => void; onChartLoad?: (event: UnifiedHistogramChartLoadEvent) => void; + onFilter?: LensEmbeddableInput['onFilter']; + onBrushEnd?: LensEmbeddableInput['onBrushEnd']; } export function Histogram({ services: { data, lens, uiSettings }, dataView, - lastReloadRequestTime, request, hits, chart: { timeInterval }, - timeRange, + getTimeRange, + refetch$, lensAttributes: attributes, + disableTriggers, + disabledActions, onTotalHitsChange, onChartLoad, + onFilter, + onBrushEnd, }: HistogramProps) { const [bucketInterval, setBucketInterval] = useState(); const { timeRangeText, timeRangeDisplay } = useTimeRange({ uiSettings, bucketInterval, - timeRange, + timeRange: getTimeRange(), timeInterval, }); - // Keep track of previous hits in a ref to avoid recreating the - // onLoad callback when the hits change, which triggers a Lens reload - const previousHits = useRef(hits?.total); - - useEffect(() => { - previousHits.current = hits?.total; - }, [hits?.total]); - - const onLoad = useCallback( + const onLoad = useStableCallback( (isLoading: boolean, adapters: Partial | undefined) => { const lensRequest = adapters?.requests?.getRequests()[0]; const requestFailed = lensRequest?.status === RequestStatus.ERROR; @@ -86,7 +87,7 @@ export function Histogram({ // This is incorrect, so we check for request failures and shard failures here, and emit an error instead. if (requestFailed || response?._shards.failed) { onTotalHitsChange?.(UnifiedHistogramFetchStatus.error, undefined); - onChartLoad?.({ complete: false, adapters: adapters ?? {} }); + onChartLoad?.({ adapters: adapters ?? {} }); return; } @@ -94,7 +95,7 @@ export function Histogram({ onTotalHitsChange?.( isLoading ? UnifiedHistogramFetchStatus.loading : UnifiedHistogramFetchStatus.complete, - totalHits ?? previousHits.current + totalHits ?? hits?.total ); if (response) { @@ -102,18 +103,25 @@ export function Histogram({ data, dataView, timeInterval, - timeRange, + timeRange: getTimeRange(), response, }); setBucketInterval(newBucketInterval); } - onChartLoad?.({ complete: !isLoading, adapters: adapters ?? {} }); - }, - [data, dataView, onChartLoad, onTotalHitsChange, timeInterval, timeRange] + onChartLoad?.({ adapters: adapters ?? {} }); + } ); + const lensProps = useLensProps({ + request, + getTimeRange, + refetch$, + attributes, + onLoad, + }); + const { euiTheme } = useEuiTheme(); const chartCss = css` position: relative; @@ -135,58 +143,18 @@ export function Histogram({ } `; - const [debouncedProps, setDebouncedProps] = useState( - getLensProps({ - timeRange, - attributes, - request, - lastReloadRequestTime, - onLoad, - }) - ); - - useDebounce( - () => { - setDebouncedProps( - getLensProps({ timeRange, attributes, request, lastReloadRequestTime, onLoad }) - ); - }, - REQUEST_DEBOUNCE_MS, - [attributes, lastReloadRequestTime, onLoad, request, timeRange] - ); - return ( <>

    {timeRangeDisplay} ); } - -export const getLensProps = ({ - timeRange, - attributes, - request, - lastReloadRequestTime, - onLoad, -}: { - timeRange: TimeRange; - attributes: TypedLensByValueInput['attributes']; - request: UnifiedHistogramRequestContext | undefined; - lastReloadRequestTime: number | undefined; - onLoad: (isLoading: boolean, adapters: Partial | undefined) => void; -}) => ({ - id: 'unifiedHistogramLensComponent', - viewMode: ViewMode.VIEW, - timeRange, - attributes, - noPadding: true, - searchSessionId: request?.searchSessionId, - executionContext: { - description: 'fetch chart data and total hits', - }, - lastReloadRequestTime, - onLoad, -}); diff --git a/src/plugins/unified_histogram/public/chart/use_lens_props.test.ts b/src/plugins/unified_histogram/public/chart/use_lens_props.test.ts new file mode 100644 index 0000000000000..289536edd0232 --- /dev/null +++ b/src/plugins/unified_histogram/public/chart/use_lens_props.test.ts @@ -0,0 +1,93 @@ +/* + * 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 { renderHook } from '@testing-library/react-hooks'; +import { act } from 'react-test-renderer'; +import { Subject } from 'rxjs'; +import type { UnifiedHistogramInputMessage } from '../types'; +import { dataViewWithTimefieldMock } from '../__mocks__/data_view_with_timefield'; +import { getLensAttributes } from './get_lens_attributes'; +import { getLensProps, useLensProps } from './use_lens_props'; + +describe('useLensProps', () => { + it('should return lens props', () => { + const getTimeRange = jest.fn(); + const refetch$ = new Subject(); + const onLoad = jest.fn(); + const attributes = getLensAttributes({ + title: 'test', + filters: [], + query: { + language: 'kuery', + query: '', + }, + dataView: dataViewWithTimefieldMock, + timeInterval: 'auto', + breakdownField: dataViewWithTimefieldMock.getFieldByName('extension'), + }); + const lensProps = renderHook(() => { + return useLensProps({ + request: { + searchSessionId: 'id', + adapter: undefined, + }, + getTimeRange, + refetch$, + attributes, + onLoad, + }); + }); + expect(lensProps.result.current).toEqual( + getLensProps({ + searchSessionId: 'id', + getTimeRange, + attributes, + onLoad, + }) + ); + }); + + it('should only update lens props when refetch$ is triggered', () => { + const getTimeRange = jest.fn(); + const refetch$ = new Subject(); + const onLoad = jest.fn(); + const lensProps = { + request: { + searchSessionId: '123', + adapter: undefined, + }, + getTimeRange, + refetch$, + attributes: getLensAttributes({ + title: 'test', + filters: [], + query: { + language: 'kuery', + query: '', + }, + dataView: dataViewWithTimefieldMock, + timeInterval: 'auto', + breakdownField: dataViewWithTimefieldMock.getFieldByName('extension'), + }), + onLoad, + }; + const hook = renderHook( + (props) => { + return useLensProps(props); + }, + { initialProps: lensProps } + ); + const originalProps = hook.result.current; + hook.rerender({ ...lensProps, request: { searchSessionId: '456', adapter: undefined } }); + expect(hook.result.current).toEqual(originalProps); + act(() => { + refetch$.next({ type: 'refetch' }); + }); + expect(hook.result.current).not.toEqual(originalProps); + }); +}); diff --git a/src/plugins/unified_histogram/public/chart/use_lens_props.ts b/src/plugins/unified_histogram/public/chart/use_lens_props.ts new file mode 100644 index 0000000000000..976f191dba5c3 --- /dev/null +++ b/src/plugins/unified_histogram/public/chart/use_lens_props.ts @@ -0,0 +1,74 @@ +/* + * 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 { TimeRange } from '@kbn/data-plugin/common'; +import { ViewMode } from '@kbn/embeddable-plugin/public'; +import type { DefaultInspectorAdapters } from '@kbn/expressions-plugin/common'; +import type { TypedLensByValueInput } from '@kbn/lens-plugin/public'; +import { useCallback, useEffect, useState } from 'react'; +import type { Observable } from 'rxjs'; +import type { UnifiedHistogramInputMessage, UnifiedHistogramRequestContext } from '../types'; +import { useStableCallback } from './use_stable_callback'; + +export const useLensProps = ({ + request, + getTimeRange, + refetch$, + attributes, + onLoad, +}: { + request?: UnifiedHistogramRequestContext; + getTimeRange: () => TimeRange; + refetch$: Observable; + attributes: TypedLensByValueInput['attributes']; + onLoad: (isLoading: boolean, adapters: Partial | undefined) => void; +}) => { + const buildLensProps = useCallback( + () => + getLensProps({ + searchSessionId: request?.searchSessionId, + getTimeRange, + attributes, + onLoad, + }), + [attributes, getTimeRange, onLoad, request?.searchSessionId] + ); + + const [lensProps, setLensProps] = useState(buildLensProps()); + const updateLensProps = useStableCallback(() => setLensProps(buildLensProps())); + + useEffect(() => { + const subscription = refetch$.subscribe(updateLensProps); + return () => subscription.unsubscribe(); + }, [refetch$, updateLensProps]); + + return lensProps; +}; + +export const getLensProps = ({ + searchSessionId, + getTimeRange, + attributes, + onLoad, +}: { + searchSessionId?: string; + getTimeRange: () => TimeRange; + attributes: TypedLensByValueInput['attributes']; + onLoad: (isLoading: boolean, adapters: Partial | undefined) => void; +}) => ({ + id: 'unifiedHistogramLensComponent', + viewMode: ViewMode.VIEW, + timeRange: getTimeRange(), + attributes, + noPadding: true, + searchSessionId, + executionContext: { + description: 'fetch chart data and total hits', + }, + onLoad, +}); diff --git a/src/plugins/unified_histogram/public/chart/use_refetch.test.ts b/src/plugins/unified_histogram/public/chart/use_refetch.test.ts new file mode 100644 index 0000000000000..39381ea661865 --- /dev/null +++ b/src/plugins/unified_histogram/public/chart/use_refetch.test.ts @@ -0,0 +1,85 @@ +/* + * 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 { useRefetch } from './use_refetch'; +import { DataView } from '@kbn/data-views-plugin/common'; +import { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query'; +import { renderHook } from '@testing-library/react-hooks'; +import { + UnifiedHistogramBreakdownContext, + UnifiedHistogramChartContext, + UnifiedHistogramHitsContext, + UnifiedHistogramInput$, + UnifiedHistogramRequestContext, +} from '../types'; +import { dataViewWithTimefieldMock } from '../__mocks__/data_view_with_timefield'; +import { Subject } from 'rxjs'; + +describe('useRefetch', () => { + const getDeps: () => { + dataView: DataView; + request: UnifiedHistogramRequestContext | undefined; + hits: UnifiedHistogramHitsContext | undefined; + chart: UnifiedHistogramChartContext | undefined; + chartVisible: boolean; + breakdown: UnifiedHistogramBreakdownContext | undefined; + filters: Filter[]; + query: Query | AggregateQuery; + relativeTimeRange: TimeRange; + input$: UnifiedHistogramInput$; + beforeRefetch: () => void; + } = () => ({ + dataView: dataViewWithTimefieldMock, + request: undefined, + hits: undefined, + chart: undefined, + chartVisible: true, + breakdown: undefined, + filters: [], + query: { language: 'kuery', query: '' }, + relativeTimeRange: { from: 'now-15m', to: 'now' }, + input$: new Subject(), + beforeRefetch: () => {}, + }); + + it('should trigger the refetch observable when any of the arguments change', () => { + const originalDeps = getDeps(); + const hook = renderHook((deps) => useRefetch(deps), { + initialProps: originalDeps, + }); + const refetch = jest.fn(); + hook.result.current.subscribe(refetch); + hook.rerender({ ...originalDeps }); + expect(refetch).not.toHaveBeenCalled(); + hook.rerender({ ...originalDeps, chartVisible: false }); + expect(refetch).toHaveBeenCalledTimes(1); + }); + + it('should not trigger the refetch observable when disableAutoFetching is true', () => { + const originalDeps = { ...getDeps(), disableAutoFetching: true }; + const hook = renderHook((deps) => useRefetch(deps), { + initialProps: originalDeps, + }); + const refetch = jest.fn(); + hook.result.current.subscribe(refetch); + hook.rerender({ ...originalDeps, chartVisible: false }); + expect(refetch).not.toHaveBeenCalled(); + }); + + it('should trigger the refetch observable when the input$ observable is triggered', () => { + const originalDeps = { ...getDeps(), disableAutoFetching: true }; + const hook = renderHook((deps) => useRefetch(deps), { + initialProps: originalDeps, + }); + const refetch = jest.fn(); + hook.result.current.subscribe(refetch); + expect(refetch).not.toHaveBeenCalled(); + originalDeps.input$.next({ type: 'refetch' }); + expect(refetch).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/plugins/unified_histogram/public/chart/use_refetch_id.ts b/src/plugins/unified_histogram/public/chart/use_refetch.ts similarity index 79% rename from src/plugins/unified_histogram/public/chart/use_refetch_id.ts rename to src/plugins/unified_histogram/public/chart/use_refetch.ts index 4415be9ccd8b6..31e08f3d732e5 100644 --- a/src/plugins/unified_histogram/public/chart/use_refetch_id.ts +++ b/src/plugins/unified_histogram/public/chart/use_refetch.ts @@ -9,17 +9,18 @@ import type { DataView } from '@kbn/data-views-plugin/common'; import type { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query'; import { cloneDeep, isEqual } from 'lodash'; -import { useEffect, useRef, useState } from 'react'; -import type { +import { useEffect, useMemo, useRef } from 'react'; +import { filter, share, tap } from 'rxjs'; +import { UnifiedHistogramBreakdownContext, UnifiedHistogramChartContext, UnifiedHistogramHitsContext, + UnifiedHistogramInput$, UnifiedHistogramRequestContext, } from '../types'; -export const useRefetchId = ({ +export const useRefetch = ({ dataView, - lastReloadRequestTime, request, hits, chart, @@ -27,10 +28,12 @@ export const useRefetchId = ({ breakdown, filters, query, - relativeTimeRange: relativeTimeRange, + relativeTimeRange, + disableAutoFetching, + input$, + beforeRefetch, }: { dataView: DataView; - lastReloadRequestTime: number | undefined; request: UnifiedHistogramRequestContext | undefined; hits: UnifiedHistogramHitsContext | undefined; chart: UnifiedHistogramChartContext | undefined; @@ -39,17 +42,23 @@ export const useRefetchId = ({ filters: Filter[]; query: Query | AggregateQuery; relativeTimeRange: TimeRange; + disableAutoFetching?: boolean; + input$: UnifiedHistogramInput$; + beforeRefetch: () => void; }) => { const refetchDeps = useRef>(); - const [refetchId, setRefetchId] = useState(0); // When the unified histogram props change, we must compare the current subset // that should trigger a histogram refetch against the previous subset. If they // are different, we must refetch the histogram to ensure it's up to date. useEffect(() => { + // Skip if auto fetching if disabled + if (disableAutoFetching) { + return; + } + const newRefetchDeps = getRefetchDeps({ dataView, - lastReloadRequestTime, request, hits, chart, @@ -62,7 +71,7 @@ export const useRefetchId = ({ if (!isEqual(refetchDeps.current, newRefetchDeps)) { if (refetchDeps.current) { - setRefetchId((id) => id + 1); + input$.next({ type: 'refetch' }); } refetchDeps.current = newRefetchDeps; @@ -72,20 +81,28 @@ export const useRefetchId = ({ chart, chartVisible, dataView, + disableAutoFetching, filters, hits, - lastReloadRequestTime, + input$, query, - request, relativeTimeRange, + request, ]); - return refetchId; + return useMemo( + () => + input$.pipe( + filter((message) => message.type === 'refetch'), + tap(beforeRefetch), + share() + ), + [beforeRefetch, input$] + ); }; const getRefetchDeps = ({ dataView, - lastReloadRequestTime, request, hits, chart, @@ -96,7 +113,6 @@ const getRefetchDeps = ({ relativeTimeRange, }: { dataView: DataView; - lastReloadRequestTime: number | undefined; request: UnifiedHistogramRequestContext | undefined; hits: UnifiedHistogramHitsContext | undefined; chart: UnifiedHistogramChartContext | undefined; @@ -108,7 +124,6 @@ const getRefetchDeps = ({ }) => cloneDeep([ dataView.id, - lastReloadRequestTime, request?.searchSessionId, Boolean(hits), chartVisible, diff --git a/src/plugins/unified_histogram/public/chart/use_refetch_id.test.ts b/src/plugins/unified_histogram/public/chart/use_refetch_id.test.ts deleted file mode 100644 index 8835173df2599..0000000000000 --- a/src/plugins/unified_histogram/public/chart/use_refetch_id.test.ts +++ /dev/null @@ -1,68 +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 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 { DataView } from '@kbn/data-views-plugin/common'; -import { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query'; -import { renderHook } from '@testing-library/react-hooks'; -import { - UnifiedHistogramBreakdownContext, - UnifiedHistogramChartContext, - UnifiedHistogramHitsContext, - UnifiedHistogramRequestContext, -} from '../types'; -import { dataViewWithTimefieldMock } from '../__mocks__/data_view_with_timefield'; -import { useRefetchId } from './use_refetch_id'; - -describe('useRefetchId', () => { - const getDeps: () => { - dataView: DataView; - lastReloadRequestTime: number | undefined; - request: UnifiedHistogramRequestContext | undefined; - hits: UnifiedHistogramHitsContext | undefined; - chart: UnifiedHistogramChartContext | undefined; - chartVisible: boolean; - breakdown: UnifiedHistogramBreakdownContext | undefined; - filters: Filter[]; - query: Query | AggregateQuery; - relativeTimeRange: TimeRange; - } = () => ({ - dataView: dataViewWithTimefieldMock, - lastReloadRequestTime: 0, - request: undefined, - hits: undefined, - chart: undefined, - chartVisible: true, - breakdown: undefined, - filters: [], - query: { language: 'kuery', query: '' }, - relativeTimeRange: { from: 'now-15m', to: 'now' }, - }); - - it('should increment the refetchId when any of the arguments change', () => { - const hook = renderHook((props) => useRefetchId(props), { initialProps: getDeps() }); - expect(hook.result.current).toBe(0); - hook.rerender(getDeps()); - expect(hook.result.current).toBe(0); - hook.rerender({ - ...getDeps(), - lastReloadRequestTime: 1, - }); - expect(hook.result.current).toBe(1); - hook.rerender({ - ...getDeps(), - lastReloadRequestTime: 1, - }); - expect(hook.result.current).toBe(1); - hook.rerender({ - ...getDeps(), - lastReloadRequestTime: 1, - query: { language: 'kuery', query: 'foo' }, - }); - expect(hook.result.current).toBe(2); - }); -}); diff --git a/src/plugins/unified_histogram/public/chart/use_request_params.test.ts b/src/plugins/unified_histogram/public/chart/use_request_params.test.ts new file mode 100644 index 0000000000000..c49bcd4ce195b --- /dev/null +++ b/src/plugins/unified_histogram/public/chart/use_request_params.test.ts @@ -0,0 +1,48 @@ +/* + * 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 { renderHook } from '@testing-library/react-hooks'; +import { unifiedHistogramServicesMock } from '../__mocks__/services'; + +const getUseRequestParams = async () => { + jest.doMock('@kbn/data-plugin/common', () => { + return { + ...jest.requireActual('@kbn/data-plugin/common'), + getAbsoluteTimeRange: jest.fn((range) => range), + }; + }); + return (await import('./use_request_params')).useRequestParams; +}; + +describe('useRequestParams', () => { + it('should only update getTimeRange after updateTimeRange is called', async () => { + const useRequestParams = await getUseRequestParams(); + const originalTimeRange = { + from: 'now-15m', + to: 'now', + }; + const originalProps = { + services: unifiedHistogramServicesMock, + timeRange: originalTimeRange, + filters: [], + query: { + query: '', + language: 'kuery', + }, + }; + const hook = renderHook((props) => useRequestParams(props), { + initialProps: originalProps, + }); + expect(hook.result.current.getTimeRange()).toEqual(originalTimeRange); + const newTimeRange = { from: 'now-30m', to: 'now' }; + hook.rerender({ ...originalProps, timeRange: newTimeRange }); + expect(hook.result.current.getTimeRange()).toEqual(originalTimeRange); + hook.result.current.updateTimeRange(); + expect(hook.result.current.getTimeRange()).toEqual(newTimeRange); + }); +}); diff --git a/src/plugins/unified_histogram/public/chart/use_request_params.tsx b/src/plugins/unified_histogram/public/chart/use_request_params.tsx index defa2bdd920d9..8afe803d329af 100644 --- a/src/plugins/unified_histogram/public/chart/use_request_params.tsx +++ b/src/plugins/unified_histogram/public/chart/use_request_params.tsx @@ -6,53 +6,42 @@ * Side Public License, v 1. */ -import { connectToQueryState, QueryState } from '@kbn/data-plugin/public'; -import { createStateContainer, useContainerState } from '@kbn/kibana-utils-plugin/public'; -import { useEffect, useMemo, useRef } from 'react'; -import type { UnifiedHistogramRequestContext, UnifiedHistogramServices } from '../types'; +import { getAbsoluteTimeRange } from '@kbn/data-plugin/common'; +import type { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query'; +import { useCallback, useMemo, useRef } from 'react'; +import type { UnifiedHistogramServices } from '../types'; +import { useStableCallback } from './use_stable_callback'; export const useRequestParams = ({ services, - lastReloadRequestTime, - request, + query: originalQuery, + filters: originalFilters, + timeRange: originalTimeRange, }: { services: UnifiedHistogramServices; - lastReloadRequestTime: number | undefined; - request?: UnifiedHistogramRequestContext; + query?: Query | AggregateQuery; + filters?: Filter[]; + timeRange?: TimeRange; }) => { const { data } = services; - const queryStateContainer = useRef( - createStateContainer({ - filters: data.query.filterManager.getFilters(), - query: data.query.queryString.getQuery(), - refreshInterval: data.query.timefilter.timefilter.getRefreshInterval(), - time: data.query.timefilter.timefilter.getTime(), - }) - ).current; - - const queryState = useContainerState(queryStateContainer); - - useEffect(() => { - return connectToQueryState(data.query, queryStateContainer, { - time: true, - query: true, - filters: true, - refreshInterval: true, - }); - }, [data.query, queryStateContainer]); - - const filters = useMemo(() => queryState.filters ?? [], [queryState.filters]); + const filters = useMemo(() => originalFilters ?? [], [originalFilters]); const query = useMemo( - () => queryState.query ?? data.query.queryString.getDefaultQuery(), - [data.query.queryString, queryState.query] + () => originalQuery ?? data.query.queryString.getDefaultQuery(), + [data.query.queryString, originalQuery] ); const relativeTimeRange = useMemo( - () => queryState.time ?? data.query.timefilter.timefilter.getTimeDefaults(), - [data.query.timefilter.timefilter, queryState.time] + () => originalTimeRange ?? data.query.timefilter.timefilter.getTimeDefaults(), + [data.query.timefilter.timefilter, originalTimeRange] ); - return { filters, query, relativeTimeRange }; + const timeRange = useRef(getAbsoluteTimeRange(relativeTimeRange)); + const getTimeRange = useCallback(() => timeRange.current, []); + const updateTimeRange = useStableCallback(() => { + timeRange.current = getAbsoluteTimeRange(relativeTimeRange); + }); + + return { filters, query, getTimeRange, updateTimeRange, relativeTimeRange }; }; diff --git a/src/plugins/unified_histogram/public/chart/use_stable_callback.test.ts b/src/plugins/unified_histogram/public/chart/use_stable_callback.test.ts new file mode 100644 index 0000000000000..2ea1be911df0e --- /dev/null +++ b/src/plugins/unified_histogram/public/chart/use_stable_callback.test.ts @@ -0,0 +1,19 @@ +/* + * 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 { renderHook } from '@testing-library/react-hooks'; +import { useStableCallback } from './use_stable_callback'; + +describe('useStableCallback', () => { + it('should return a stable callback', () => { + const hook = renderHook((cb) => useStableCallback(cb), { initialProps: () => {} }); + const firstCallback = hook.result.current; + hook.rerender(() => {}); + expect(hook.result.current).toBe(firstCallback); + }); +}); diff --git a/src/plugins/unified_histogram/public/chart/use_stable_callback.ts b/src/plugins/unified_histogram/public/chart/use_stable_callback.ts new file mode 100644 index 0000000000000..9b81470c5ff5c --- /dev/null +++ b/src/plugins/unified_histogram/public/chart/use_stable_callback.ts @@ -0,0 +1,23 @@ +/* + * 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 { useCallback, useEffect, useRef } from 'react'; + +/** + * Accepts a callback and returns a function with a stable identity + * that will always call the latest version of the callback when invoked + */ +export const useStableCallback = any>(fn: T | undefined) => { + const ref = useRef(fn); + + useEffect(() => { + ref.current = fn; + }, [fn]); + + return useCallback((...args: Parameters) => ref.current?.(...args), []); +}; diff --git a/src/plugins/unified_histogram/public/chart/use_total_hits.test.ts b/src/plugins/unified_histogram/public/chart/use_total_hits.test.ts index 4782df3683fcb..ea6ab4676e681 100644 --- a/src/plugins/unified_histogram/public/chart/use_total_hits.test.ts +++ b/src/plugins/unified_histogram/public/chart/use_total_hits.test.ts @@ -7,14 +7,14 @@ */ import { Filter } from '@kbn/es-query'; -import { UnifiedHistogramFetchStatus } from '../types'; +import { UnifiedHistogramFetchStatus, UnifiedHistogramInput$ } from '../types'; import { dataViewWithTimefieldMock } from '../__mocks__/data_view_with_timefield'; import { useTotalHits } from './use_total_hits'; import { useEffect as mockUseEffect } from 'react'; import { renderHook } from '@testing-library/react-hooks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { searchSourceInstanceMock } from '@kbn/data-plugin/common/search/search_source/mocks'; -import { of, throwError } from 'rxjs'; +import { of, Subject, throwError } from 'rxjs'; import { waitFor } from '@testing-library/dom'; import { RequestAdapter } from '@kbn/inspector-plugin/common'; import { DataViewType, SearchSourceSearchOptions } from '@kbn/data-plugin/common'; @@ -26,25 +26,21 @@ jest.mock('react-use/lib/useDebounce', () => { }); describe('useTotalHits', () => { + const timeRange = { from: 'now-15m', to: 'now' }; + const refetch$: UnifiedHistogramInput$ = new Subject(); const getDeps = () => ({ services: { data: dataPluginMock.createStartContract() } as any, dataView: dataViewWithTimefieldMock, - lastReloadRequestTime: undefined, request: undefined, hits: { status: UnifiedHistogramFetchStatus.uninitialized, total: undefined, }, - chart: { - hidden: true, - timeInterval: 'auto', - }, chartVisible: false, - breakdown: undefined, filters: [], query: { query: '', language: 'kuery' }, - timeRange: { from: 'now-15m', to: 'now' }, - refetchId: 0, + getTimeRange: () => timeRange, + refetch$, onTotalHitsChange: jest.fn(), }); @@ -68,7 +64,6 @@ describe('useTotalHits', () => { }); const setFieldSpy = jest.spyOn(searchSourceInstanceMock, 'setField').mockClear(); const data = dataPluginMock.createStartContract(); - const timeRange = { from: 'now-15m', to: 'now' }; jest .spyOn(data.query.timefilter.timefilter, 'createFilter') .mockClear() @@ -86,7 +81,7 @@ describe('useTotalHits', () => { }, query, filters, - timeRange, + refetch$, onTotalHitsChange, }) ); @@ -128,11 +123,11 @@ describe('useTotalHits', () => { expect(fetchSpy).not.toHaveBeenCalled(); }); - it('should not fetch a second time if fetchId is the same', async () => { + it('should not fetch a second time if refetch$ is not triggered', async () => { const onTotalHitsChange = jest.fn(); const fetchSpy = jest.spyOn(searchSourceInstanceMock, 'fetch$').mockClear(); const setFieldSpy = jest.spyOn(searchSourceInstanceMock, 'setField').mockClear(); - const options = { ...getDeps(), refetchId: 0, onTotalHitsChange }; + const options = { ...getDeps(), onTotalHitsChange }; const { rerender } = renderHook(() => useTotalHits(options)); expect(onTotalHitsChange).toBeCalledTimes(1); expect(setFieldSpy).toHaveBeenCalled(); @@ -146,12 +141,12 @@ describe('useTotalHits', () => { expect(fetchSpy).toHaveBeenCalledTimes(1); }); - it('should fetch a second time if fetchId is different', async () => { + it('should fetch a second time if refetch$ is triggered', async () => { const abortSpy = jest.spyOn(AbortController.prototype, 'abort').mockClear(); const onTotalHitsChange = jest.fn(); const fetchSpy = jest.spyOn(searchSourceInstanceMock, 'fetch$').mockClear(); const setFieldSpy = jest.spyOn(searchSourceInstanceMock, 'setField').mockClear(); - const options = { ...getDeps(), refetchId: 0, onTotalHitsChange }; + const options = { ...getDeps(), onTotalHitsChange }; const { rerender } = renderHook(() => useTotalHits(options)); expect(onTotalHitsChange).toBeCalledTimes(1); expect(setFieldSpy).toHaveBeenCalled(); @@ -159,7 +154,7 @@ describe('useTotalHits', () => { await waitFor(() => { expect(onTotalHitsChange).toBeCalledTimes(2); }); - options.refetchId = 1; + refetch$.next({ type: 'refetch' }); rerender(); expect(abortSpy).toHaveBeenCalled(); expect(onTotalHitsChange).toBeCalledTimes(3); @@ -190,7 +185,6 @@ describe('useTotalHits', () => { .mockClear(); const setFieldSpy = jest.spyOn(searchSourceInstanceMock, 'setField').mockClear(); const data = dataPluginMock.createStartContract(); - const timeRange = { from: 'now-15m', to: 'now' }; jest .spyOn(data.query.timefilter.timefilter, 'createFilter') .mockClear() diff --git a/src/plugins/unified_histogram/public/chart/use_total_hits.ts b/src/plugins/unified_histogram/public/chart/use_total_hits.ts index 3f24b642c81bf..e7227edd76684 100644 --- a/src/plugins/unified_histogram/public/chart/use_total_hits.ts +++ b/src/plugins/unified_histogram/public/chart/use_total_hits.ts @@ -10,68 +10,63 @@ import { isCompleteResponse } from '@kbn/data-plugin/public'; import { DataView, DataViewType } from '@kbn/data-views-plugin/public'; import type { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; -import { MutableRefObject, useRef } from 'react'; -import useDebounce from 'react-use/lib/useDebounce'; -import { catchError, filter, lastValueFrom, map, of } from 'rxjs'; +import { MutableRefObject, useEffect, useRef } from 'react'; +import useEffectOnce from 'react-use/lib/useEffectOnce'; +import { catchError, filter, lastValueFrom, map, Observable, of } from 'rxjs'; import { - UnifiedHistogramBreakdownContext, - UnifiedHistogramChartContext, UnifiedHistogramFetchStatus, UnifiedHistogramHitsContext, + UnifiedHistogramInputMessage, UnifiedHistogramRequestContext, UnifiedHistogramServices, } from '../types'; -import { REQUEST_DEBOUNCE_MS } from './consts'; +import { useStableCallback } from './use_stable_callback'; export const useTotalHits = ({ services, dataView, - lastReloadRequestTime, request, hits, - chart, chartVisible, - breakdown, filters, query, - timeRange, - refetchId, + getTimeRange, + refetch$, onTotalHitsChange, }: { services: UnifiedHistogramServices; dataView: DataView; - lastReloadRequestTime: number | undefined; request: UnifiedHistogramRequestContext | undefined; hits: UnifiedHistogramHitsContext | undefined; - chart: UnifiedHistogramChartContext | undefined; chartVisible: boolean; - breakdown: UnifiedHistogramBreakdownContext | undefined; filters: Filter[]; query: Query | AggregateQuery; - timeRange: TimeRange; - refetchId: number; + getTimeRange: () => TimeRange; + refetch$: Observable; onTotalHitsChange?: (status: UnifiedHistogramFetchStatus, result?: number | Error) => void; }) => { const abortController = useRef(); - - useDebounce( - () => { - fetchTotalHits({ - services, - abortController, - dataView, - request, - hits, - chartVisible, - filters, - query, - timeRange, - onTotalHitsChange, - }); - }, - REQUEST_DEBOUNCE_MS, - [onTotalHitsChange, refetchId, services] - ); + const fetch = useStableCallback(() => { + fetchTotalHits({ + services, + abortController, + dataView, + request, + hits, + chartVisible, + filters, + query, + timeRange: getTimeRange(), + onTotalHitsChange, + }); + }); + + useEffectOnce(fetch); + + useEffect(() => { + const subscription = refetch$.subscribe(fetch); + return () => subscription.unsubscribe(); + }, [fetch, refetch$]); }; const fetchTotalHits = async ({ diff --git a/src/plugins/unified_histogram/public/index.ts b/src/plugins/unified_histogram/public/index.ts index 4a8f73477c0b6..97cebb51fdc2f 100644 --- a/src/plugins/unified_histogram/public/index.ts +++ b/src/plugins/unified_histogram/public/index.ts @@ -18,6 +18,9 @@ export type { UnifiedHistogramBreakdownContext, UnifiedHistogramChartLoadEvent, UnifiedHistogramAdapters, + UnifiedHistogramRefetchMessage, + UnifiedHistogramInputMessage, + UnifiedHistogramInput$, } from './types'; export { UnifiedHistogramFetchStatus } from './types'; diff --git a/src/plugins/unified_histogram/public/layout/layout.test.tsx b/src/plugins/unified_histogram/public/layout/layout.test.tsx index d77bbfa05be30..aee62e3c7d3b8 100644 --- a/src/plugins/unified_histogram/public/layout/layout.test.tsx +++ b/src/plugins/unified_histogram/public/layout/layout.test.tsx @@ -56,14 +56,6 @@ describe('Layout', () => { hits?: UnifiedHistogramHitsContext | null; chart?: UnifiedHistogramChartContext | null; } = {}) => { - services.data.query.timefilter.timefilter.getAbsoluteTime = () => { - return { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }; - }; - - (services.data.query.queryString.getDefaultQuery as jest.Mock).mockReturnValue({ - language: 'kuery', - query: '', - }); (searchSourceInstanceMock.fetch$ as jest.Mock).mockImplementation( jest.fn().mockReturnValue(of({ rawResponse: { hits: { total: 2 } } })) ); @@ -75,6 +67,15 @@ describe('Layout', () => { chart={chart ?? undefined} resizeRef={resizeRef} dataView={dataViewWithTimefieldMock} + query={{ + language: 'kuery', + query: '', + }} + filters={[]} + timeRange={{ + from: '2020-05-14T11:05:13.590', + to: '2020-05-14T11:20:13.590', + }} {...rest} /> ); diff --git a/src/plugins/unified_histogram/public/layout/layout.tsx b/src/plugins/unified_histogram/public/layout/layout.tsx index 87d4170a1035f..db6a161a81b7e 100644 --- a/src/plugins/unified_histogram/public/layout/layout.tsx +++ b/src/plugins/unified_histogram/public/layout/layout.tsx @@ -12,7 +12,8 @@ import React, { useMemo } from 'react'; import { createHtmlPortalNode, InPortal, OutPortal } from 'react-reverse-portal'; import { css } from '@emotion/css'; import type { DataView, DataViewField } from '@kbn/data-views-plugin/public'; -import type { TypedLensByValueInput } from '@kbn/lens-plugin/public'; +import type { LensEmbeddableInput, TypedLensByValueInput } from '@kbn/lens-plugin/public'; +import type { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query'; import { Chart } from '../chart'; import { Panels, PANELS_MODE } from '../panels'; import type { @@ -23,6 +24,7 @@ import type { UnifiedHistogramFetchStatus, UnifiedHistogramRequestContext, UnifiedHistogramChartLoadEvent, + UnifiedHistogramInput$, } from '../types'; export interface UnifiedHistogramLayoutProps extends PropsWithChildren { @@ -39,9 +41,17 @@ export interface UnifiedHistogramLayoutProps extends PropsWithChildren */ dataView: DataView; /** - * Can be updated to `Date.now()` to force a refresh + * The current query */ - lastReloadRequestTime?: number; + query?: Query | AggregateQuery; + /** + * The current filters + */ + filters?: Filter[]; + /** + * The current time range + */ + timeRange?: TimeRange; /** * Context object for requests made by unified histogram components -- optional */ @@ -70,6 +80,22 @@ export interface UnifiedHistogramLayoutProps extends PropsWithChildren * Append a custom element to the right of the hits count */ appendHitsCounter?: ReactElement; + /** + * Disable automatic refetching based on props changes, and instead wait for a `refetch` message + */ + disableAutoFetching?: boolean; + /** + * Disable triggers for the Lens embeddable + */ + disableTriggers?: LensEmbeddableInput['disableTriggers']; + /** + * Disabled action IDs for the Lens embeddable + */ + disabledActions?: LensEmbeddableInput['disabledActions']; + /** + * Input observable + */ + input$?: UnifiedHistogramInput$; /** * Callback to update the topPanelHeight prop when a resize is triggered */ @@ -99,13 +125,23 @@ export interface UnifiedHistogramLayoutProps extends PropsWithChildren * Called when the histogram loading status changes */ onChartLoad?: (event: UnifiedHistogramChartLoadEvent) => void; + /** + * Callback to pass to the Lens embeddable to handle filter changes + */ + onFilter?: LensEmbeddableInput['onFilter']; + /** + * Callback to pass to the Lens embeddable to handle brush events + */ + onBrushEnd?: LensEmbeddableInput['onBrushEnd']; } export const UnifiedHistogramLayout = ({ className, services, dataView, - lastReloadRequestTime, + query, + filters, + timeRange, request, hits, chart, @@ -113,6 +149,10 @@ export const UnifiedHistogramLayout = ({ resizeRef, topPanelHeight, appendHitsCounter, + disableAutoFetching, + disableTriggers, + disabledActions, + input$, onTopPanelHeightChange, onEditVisualization, onChartHiddenChange, @@ -120,6 +160,8 @@ export const UnifiedHistogramLayout = ({ onBreakdownFieldChange, onTotalHitsChange, onChartLoad, + onFilter, + onBrushEnd, children, }: UnifiedHistogramLayoutProps) => { const topPanelNode = useMemo( @@ -167,13 +209,19 @@ export const UnifiedHistogramLayout = ({ className={chartClassName} services={services} dataView={dataView} - lastReloadRequestTime={lastReloadRequestTime} + query={query} + filters={filters} + timeRange={timeRange} request={request} hits={hits} chart={chart} breakdown={breakdown} appendHitsCounter={appendHitsCounter} appendHistogram={showFixedPanels ? : } + disableAutoFetching={disableAutoFetching} + disableTriggers={disableTriggers} + disabledActions={disabledActions} + input$={input$} onEditVisualization={onEditVisualization} onResetChartHeight={onResetChartHeight} onChartHiddenChange={onChartHiddenChange} @@ -181,6 +229,8 @@ export const UnifiedHistogramLayout = ({ onBreakdownFieldChange={onBreakdownFieldChange} onTotalHitsChange={onTotalHitsChange} onChartLoad={onChartLoad} + onFilter={onFilter} + onBrushEnd={onBrushEnd} /> {children} diff --git a/src/plugins/unified_histogram/public/types.ts b/src/plugins/unified_histogram/public/types.ts index a4b253274abde..f77bfa1bbdbee 100644 --- a/src/plugins/unified_histogram/public/types.ts +++ b/src/plugins/unified_histogram/public/types.ts @@ -14,6 +14,7 @@ import type { LensPublicStart } from '@kbn/lens-plugin/public'; import type { DataViewField } from '@kbn/data-views-plugin/public'; import type { RequestAdapter } from '@kbn/inspector-plugin/public'; import type { DefaultInspectorAdapters } from '@kbn/expressions-plugin/common'; +import type { Subject } from 'rxjs'; /** * The fetch status of a unified histogram request @@ -52,10 +53,6 @@ export type UnifiedHistogramAdapters = Partial; * Emitted when the histogram loading status changes */ export interface UnifiedHistogramChartLoadEvent { - /** - * True if loading is complete - */ - complete: boolean; /** * Inspector adapters for the request */ @@ -117,3 +114,20 @@ export interface UnifiedHistogramBreakdownContext { */ field?: DataViewField; } + +/** + * Message to refetch the chart and total hits + */ +export interface UnifiedHistogramRefetchMessage { + type: 'refetch'; +} + +/** + * Unified histogram input message + */ +export type UnifiedHistogramInputMessage = UnifiedHistogramRefetchMessage; + +/** + * Unified histogram input observable + */ +export type UnifiedHistogramInput$ = Subject; diff --git a/src/plugins/unified_histogram/tsconfig.json b/src/plugins/unified_histogram/tsconfig.json index a6bd54ed5e6ea..eb7da12b70b29 100644 --- a/src/plugins/unified_histogram/tsconfig.json +++ b/src/plugins/unified_histogram/tsconfig.json @@ -18,7 +18,6 @@ "@kbn/i18n", "@kbn/es-query", "@kbn/embeddable-plugin", - "@kbn/kibana-utils-plugin", "@kbn/core-ui-settings-browser", "@kbn/datemath", "@kbn/core-ui-settings-browser-mocks", diff --git a/test/functional/apps/discover/group1/_discover_histogram.ts b/test/functional/apps/discover/group1/_discover_histogram.ts index 70a1fba5afafc..e451eee881335 100644 --- a/test/functional/apps/discover/group1/_discover_histogram.ts +++ b/test/functional/apps/discover/group1/_discover_histogram.ts @@ -30,6 +30,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.load('test/functional/fixtures/es_archiver/long_window_logstash'); + await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); await kibanaServer.importExport.load( 'test/functional/fixtures/kbn_archiver/long_window_logstash_index_pattern' ); @@ -96,6 +97,20 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); }); + it('should update correctly when switching data views and brushing the histogram', async () => { + await PageObjects.common.navigateToApp('discover'); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await PageObjects.timePicker.setDefaultAbsoluteRange(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await PageObjects.discover.selectIndexPattern('logstash-*'); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await PageObjects.discover.selectIndexPattern('long-window-logstash-*'); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await PageObjects.discover.brushHistogram(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + expect(await PageObjects.discover.getHitCount()).to.be('7'); + }); + it('should update the histogram timerange when the query is resubmitted', async function () { await kibanaServer.uiSettings.update({ 'timepicker:timeDefaults': '{ "from": "2015-09-18T19:37:13.000Z", "to": "now"}', From 7a18dec079d26fbb3e924e8898d2c9d9c0407905 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 18 Jan 2023 14:31:03 +0000 Subject: [PATCH 42/44] skip flaky suite (#148092) --- .../security_and_spaces/group2/tests/alerting/alerts.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/alerts.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/alerts.ts index 9ddaf8c660d40..9fb84117347df 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/alerts.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/alerts.ts @@ -33,7 +33,8 @@ export default function alertTests({ getService }: FtrProviderContext) { const esTestIndexTool = new ESTestIndexTool(es, retry); const taskManagerUtils = new TaskManagerUtils(es, retry); - describe('alerts', () => { + // FLAKY: https://github.com/elastic/kibana/issues/148092 + describe.skip('alerts', () => { const authorizationIndex = '.kibana-test-authorization'; const alertAsDataIndex = '.internal.alerts-observability.test.alerts.alerts-default-000001'; const objectRemover = new ObjectRemover(supertest); From b3779afe9c3ba74e8269cebf9d02c4deb1bc9b55 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 18 Jan 2023 15:45:58 +0100 Subject: [PATCH 43/44] [Synthetics] Test run details step details (#149024) ## Summary Fixes https://github.com/elastic/kibana/issues/145379 Test run details step details ### Succeeded step details image ### Failed step details image --- .../common/constants/synthetics/rest_api.ts | 1 + .../common/runtime_types/ping/synthetics.ts | 4 + .../e2e/journeys/synthetics/index.ts | 1 + .../services/synthetics_services.ts | 11 +- .../synthetics/test_run_details.journey.ts | 64 +++++++ .../common/components/monitor_status.tsx | 59 ++++-- .../common/links/error_details_link.tsx | 74 ++++++++ .../common/links/step_details_link.tsx | 17 +- .../common/links/test_details_link.tsx | 20 +- .../monitor_test_result/status_badge.tsx | 12 +- .../monitor_errors/errors_list.tsx | 27 +-- .../monitor_summary/last_test_run.tsx | 14 +- .../monitor_summary/test_runs_table.tsx | 7 +- .../test_run_details/components/step_info.tsx | 93 ++++++++++ .../step_screenshot_details.tsx | 7 +- .../test_run_details/test_run_details.tsx | 4 +- .../synthetics/state/browser_journey/api.ts | 4 +- .../server/legacy_uptime/lib/lib.ts | 4 + .../server/queries/get_journey_details.ts | 172 ++++++++++++++++++ .../plugins/synthetics/server/routes/index.ts | 2 + .../server/routes/pings/journeys.ts | 80 ++++++++ 21 files changed, 612 insertions(+), 65 deletions(-) create mode 100644 x-pack/plugins/synthetics/e2e/journeys/synthetics/test_run_details.journey.ts create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/common/links/error_details_link.tsx create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/test_run_details/components/step_info.tsx create mode 100644 x-pack/plugins/synthetics/server/queries/get_journey_details.ts create mode 100644 x-pack/plugins/synthetics/server/routes/pings/journeys.ts diff --git a/x-pack/plugins/synthetics/common/constants/synthetics/rest_api.ts b/x-pack/plugins/synthetics/common/constants/synthetics/rest_api.ts index 4e41dd2190da3..d4a770f574fdd 100644 --- a/x-pack/plugins/synthetics/common/constants/synthetics/rest_api.ts +++ b/x-pack/plugins/synthetics/common/constants/synthetics/rest_api.ts @@ -14,4 +14,5 @@ export enum SYNTHETICS_API_URLS { PARAMS = `/synthetics/params`, SYNC_GLOBAL_PARAMS = `/synthetics/sync_global_params`, ENABLE_DEFAULT_ALERTING = `/synthetics/enable_default_alerting`, + JOURNEY = `/internal/synthetics/journey/{checkGroup}`, } diff --git a/x-pack/plugins/synthetics/common/runtime_types/ping/synthetics.ts b/x-pack/plugins/synthetics/common/runtime_types/ping/synthetics.ts index ae5dd0046200d..10fd7ecc6d2fe 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/ping/synthetics.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/ping/synthetics.ts @@ -7,6 +7,7 @@ import { isRight } from 'fp-ts/lib/Either'; import * as t from 'io-ts'; +import { ErrorStateCodec } from './error_state'; /** * This type has some overlap with the Ping type, but it helps avoid runtime type @@ -254,6 +255,9 @@ export const SyntheticsJourneyApiResponseType = t.intersection([ timestamp: t.string, checkGroup: t.string, }), + summary: t.type({ + state: ErrorStateCodec, + }), }), ]), t.null, diff --git a/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts b/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts index 4b4869e02877f..c7232fefb6efd 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts @@ -21,3 +21,4 @@ export * from './alert_rules/default_status_alert.journey'; export * from './test_now_mode.journey'; export * from './data_retention.journey'; export * from './monitor_details_page/monitor_summary.journey'; +export * from './test_run_details.journey'; diff --git a/x-pack/plugins/synthetics/e2e/journeys/synthetics/services/synthetics_services.ts b/x-pack/plugins/synthetics/e2e/journeys/synthetics/services/synthetics_services.ts index 67fb0d83c7f58..44b05520f5de2 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/synthetics/services/synthetics_services.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/synthetics/services/synthetics_services.ts @@ -35,7 +35,11 @@ export class SyntheticsServices { } } - async addTestMonitor(name: string, data: Record = { type: 'browser' }) { + async addTestMonitor( + name: string, + data: Record = { type: 'browser' }, + configId?: string + ) { const testData = { alert: { status: { enabled: true } }, locations: [{ id: 'us_central', isServiceManaged: true }], @@ -45,7 +49,10 @@ export class SyntheticsServices { }; try { const response = await axios.post( - this.kibanaUrl + '/internal/uptime/service/monitors', + this.kibanaUrl + + (configId + ? `/internal/uptime/service/monitors?id=${configId}` + : `/internal/uptime/service/monitors`), testData, { auth: { username: 'elastic', password: 'changeme' }, diff --git a/x-pack/plugins/synthetics/e2e/journeys/synthetics/test_run_details.journey.ts b/x-pack/plugins/synthetics/e2e/journeys/synthetics/test_run_details.journey.ts new file mode 100644 index 0000000000000..3f8df4a46cbbd --- /dev/null +++ b/x-pack/plugins/synthetics/e2e/journeys/synthetics/test_run_details.journey.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { journey, step, before, after } from '@elastic/synthetics'; +import { byTestId } from '@kbn/ux-plugin/e2e/journeys/utils'; +import { recordVideo } from '@kbn/observability-plugin/e2e/record_video'; +import { syntheticsAppPageProvider } from '../../page_objects/synthetics/synthetics_app'; +import { SyntheticsServices } from './services/synthetics_services'; + +journey(`TestRunDetailsPage`, async ({ page, params }) => { + recordVideo(page); + + page.setDefaultTimeout(60 * 1000); + const syntheticsApp = syntheticsAppPageProvider({ page, kibanaUrl: params.kibanaUrl }); + + const services = new SyntheticsServices(params); + + before(async () => { + await services.cleaUp(); + await services.enableMonitorManagedViaApi(); + await services.addTestMonitor( + 'https://www.google.com', + { + type: 'browser', + urls: 'https://www.google.com', + custom_heartbeat_id: 'a47bfc4e-361a-4eb0-83f3-b5bb68781b5b', + locations: [ + { id: 'us_central', label: 'North America - US Central', isServiceManaged: true }, + ], + }, + 'a47bfc4e-361a-4eb0-83f3-b5bb68781b5b' + ); + }); + + after(async () => { + await services.cleaUp(); + }); + + step('Go to monitor summary page', async () => { + await syntheticsApp.navigateToOverview(true); + }); + + step('Monitor is as up in summary page', async () => { + await page.hover('text=https://www.google.com'); + await page.click('[aria-label="Open actions menu"]'); + await page.click('text=Go to monitor'); + await page.waitForSelector(byTestId('monitorLatestStatusUp')); + await page.click(byTestId('syntheticsMonitorHistoryTab')); + }); + + step('Go to test run page', async () => { + await page.click(byTestId('superDatePickerToggleQuickMenuButton')); + await page.click('text=Last 1 year'); + await page.click(byTestId('row-ab240846-8d22-11ed-8fac-52bb19a2321e')); + + await page.waitForSelector('text=Test run details'); + await page.waitForSelector('text=Go to https://www.google.com'); + await page.waitForSelector('text=After 2.1 s'); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_status.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_status.tsx index c82a2e6141bfe..0f0c548160a0a 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_status.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_status.tsx @@ -9,6 +9,34 @@ import { EuiBadge, EuiDescriptionList, EuiLoadingContent } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { EncryptedSyntheticsMonitor } from '../../../../../../common/runtime_types'; +const BadgeStatus = ({ + status, + monitor, + loading, + isBrowserType, +}: { + status?: string; + loading?: boolean; + monitor: EncryptedSyntheticsMonitor; + isBrowserType: boolean; +}) => { + return loading && !monitor ? ( + + ) : !status || status === 'unknown' ? ( + + {PENDING_LABEL} + + ) : status === 'up' ? ( + + {isBrowserType ? SUCCESS_LABEL : UP_LABEL} + + ) : ( + + {isBrowserType ? FAILED_LABEL : DOWN_LABEL} + + ); +}; + export const MonitorStatus = ({ loading, monitor, @@ -22,28 +50,23 @@ export const MonitorStatus = ({ }) => { const isBrowserType = monitor.type === 'browser'; - const badge = - loading && !monitor ? ( - - ) : !status || status === 'unknown' ? ( - - {PENDING_LABEL} - - ) : status === 'up' ? ( - - {isBrowserType ? SUCCESS_LABEL : UP_LABEL} - - ) : ( - - {isBrowserType ? FAILED_LABEL : DOWN_LABEL} - - ); - return ( + ), + }, + ]} /> ); }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/links/error_details_link.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/links/error_details_link.tsx new file mode 100644 index 0000000000000..342608865a50a --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/links/error_details_link.tsx @@ -0,0 +1,74 @@ +/* + * 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 { EuiLink, EuiButtonEmpty } from '@elastic/eui'; +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { useSelectedLocation } from '../../monitor_details/hooks/use_selected_location'; +import { useSyntheticsSettingsContext } from '../../../contexts'; +import { getErrorDetailsUrl } from '../../monitor_details/monitor_errors/errors_list'; + +export const ErrorDetailsLink = ({ + stateId, + configId, + label, +}: { + configId: string; + stateId: string; + label: string; +}) => { + const { basePath } = useSyntheticsSettingsContext(); + const selectedLocation = useSelectedLocation(); + + return ( + + {label ?? VIEW_DETAILS} + + ); +}; + +export const ErrorDetailsButton = ({ + stateId, + configId, + label, +}: { + configId: string; + stateId: string; + label?: string; +}) => { + const { basePath } = useSyntheticsSettingsContext(); + const selectedLocation = useSelectedLocation(); + + if (!selectedLocation) return null; + + return ( + + {label ?? VIEW_DETAILS} + + ); +}; + +const VIEW_DETAILS = i18n.translate('xpack.synthetics.monitor.step.viewErrorDetails', { + defaultMessage: 'View error details', +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/links/step_details_link.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/links/step_details_link.tsx index f95984eafa08d..2418afb7e37a2 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/links/step_details_link.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/links/step_details_link.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiButtonIcon } from '@elastic/eui'; +import { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui'; import React from 'react'; import { i18n } from '@kbn/i18n'; import { useSelectedLocation } from '../../monitor_details/hooks/use_selected_location'; @@ -15,14 +15,29 @@ export const StepDetailsLinkIcon = ({ stepIndex, checkGroup, configId, + asButton, + label, }: { checkGroup: string; + label?: string; configId: string; stepIndex?: number; + asButton?: boolean; }) => { const { basePath } = useSyntheticsSettingsContext(); const selectedLocation = useSelectedLocation(); + if (asButton) { + return ( + + {label ?? VIEW_DETAILS} + + ); + } + return ( { const testRunUrl = `/monitor/${monitorId}/test-run/${checkGroup}?locationId=${locationId}`; - if (basePath) { - return `${basePath}/app/synthetics${testRunUrl}`; - } else { - return testRunUrl; - } + return `${basePath}/app/synthetics${testRunUrl}`; +}; + +export const getTestRunDetailRelativeLink = ({ + monitorId, + checkGroup, + locationId, +}: { + monitorId: string; + checkGroup: string; + locationId?: string; +}) => { + return `/monitor/${monitorId}/test-run/${checkGroup}?locationId=${locationId}`; }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/status_badge.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/status_badge.tsx index a18c0d7a2ca7e..acfca86c2dea0 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/status_badge.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/status_badge.tsx @@ -7,10 +7,14 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiBadge, IconColor, EuiThemeComputed } from '@elastic/eui'; +import { EuiBadge, IconColor, EuiThemeComputed, EuiLoadingContent } from '@elastic/eui'; -type MonitorStatus = 'succeeded' | 'failed' | 'skipped'; +type MonitorStatus = 'succeeded' | 'failed' | 'skipped' | 'unknown'; export const StatusBadge = ({ status }: { status: MonitorStatus }) => { + if (status === 'unknown') { + return ; + } + return ( {status === 'succeeded' ? COMPLETE_LABEL : status === 'failed' ? FAILED_LABEL : SKIPPED_LABEL} @@ -18,7 +22,7 @@ export const StatusBadge = ({ status }: { status: MonitorStatus }) => { ); }; -export const parseBadgeStatus = (status: string) => { +export const parseBadgeStatus = (status?: string) => { switch (status) { case 'succeeded': case 'success': @@ -32,7 +36,7 @@ export const parseBadgeStatus = (status: string) => { case 'skipped': return 'skipped'; default: - return 'skipped'; + return 'unknown'; } }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_errors/errors_list.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_errors/errors_list.tsx index 48f6ea76b12ed..1d7af11262287 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_errors/errors_list.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_errors/errors_list.tsx @@ -7,8 +7,9 @@ import { i18n } from '@kbn/i18n'; import React, { MouseEvent, useMemo, useState } from 'react'; -import { EuiBasicTable, EuiLink, EuiSpacer, EuiText } from '@elastic/eui'; +import { EuiBasicTable, EuiSpacer, EuiText } from '@elastic/eui'; import { useHistory, useParams } from 'react-router-dom'; +import { ErrorDetailsLink } from '../../common/links/error_details_link'; import { useSelectedLocation } from '../hooks/use_selected_location'; import { useKibanaDateFormat } from '../../../../../hooks/use_kibana_date_format'; import { Ping } from '../../../../../../common/runtime_types'; @@ -18,7 +19,6 @@ import { formatTestRunAt, } from '../../../utils/monitor_test_result/test_time_formats'; import { useMonitorErrors } from '../hooks/use_monitor_errors'; -import { useSyntheticsSettingsContext } from '../../../contexts'; export const ErrorsList = () => { const [pageIndex, setPageIndex] = useState(0); @@ -42,8 +42,6 @@ export const ErrorsList = () => { const isBrowserType = errorStates[0]?.monitor.type === 'browser'; - const { basePath } = useSyntheticsSettingsContext(); - const history = useHistory(); const format = useKibanaDateFormat(); @@ -57,16 +55,11 @@ export const ErrorsList = () => { sortable: true, render: (value: string, item: Ping) => { return ( - - {formatTestRunAt(item.state!.started_at, format)} - + ); }, }, @@ -152,16 +145,16 @@ export const ErrorsList = () => { export const getErrorDetailsUrl = ({ basePath, - monitorId, + configId, stateId, locationId, }: { stateId: string; basePath: string; - monitorId: string; + configId: string; locationId: string; }) => { - return `${basePath}/app/synthetics/monitor/${monitorId}/errors/${stateId}?locationId=${locationId}`; + return `${basePath}/app/synthetics/monitor/${configId}/errors/${stateId}?locationId=${locationId}`; }; const ERRORS_LIST_LABEL = i18n.translate('xpack.synthetics.errorsList.label', { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/last_test_run.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/last_test_run.tsx index e4c886df23d61..b22039f65ef9a 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/last_test_run.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/last_test_run.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useMemo } from 'react'; +import React from 'react'; import { EuiButton, EuiButtonEmpty, @@ -32,14 +32,13 @@ import { Ping, SyntheticsJourneyApiResponse, } from '../../../../../../common/runtime_types'; -import { formatTestRunAt } from '../../../utils/monitor_test_result/test_time_formats'; +import { useFormatTestRunAt } from '../../../utils/monitor_test_result/test_time_formats'; import { useSyntheticsRefreshContext, useSyntheticsSettingsContext } from '../../../contexts'; import { BrowserStepsList } from '../../common/monitor_test_result/browser_steps_list'; import { SinglePingResult } from '../../common/monitor_test_result/single_ping_result'; import { parseBadgeStatus, StatusBadge } from '../../common/monitor_test_result/status_badge'; -import { useKibanaDateFormat } from '../../../../../hooks/use_kibana_date_format'; import { useJourneySteps } from '../hooks/use_journey_steps'; import { useSelectedMonitor } from '../hooks/use_selected_monitor'; import { useMonitorLatestPing } from '../hooks/use_monitor_latest_ping'; @@ -108,7 +107,7 @@ export const LastTestRunComponent = ({ color="danger" href={getErrorDetailsUrl({ basePath, - monitorId: monitor?.id!, + configId: monitor?.id!, locationId: selectedLocation!.id, stateId: latestPing.state?.id!, })} @@ -153,12 +152,7 @@ const PanelHeader = ({ const { monitorId } = useParams<{ monitorId: string }>(); - const format = useKibanaDateFormat(); - - const lastRunTimestamp = useMemo( - () => (latestPing?.timestamp ? formatTestRunAt(latestPing?.timestamp, format) : ''), - [latestPing?.timestamp, format] - ); + const lastRunTimestamp = useFormatTestRunAt(latestPing?.timestamp); const isBrowserMonitor = monitor?.[ConfigKey.MONITOR_TYPE] === DataStream.BROWSER; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/test_runs_table.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/test_runs_table.tsx index e703abd8a77e2..22d124ffc4974 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/test_runs_table.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/test_runs_table.tsx @@ -24,7 +24,10 @@ import { Criteria } from '@elastic/eui/src/components/basic_table/basic_table'; import { EuiTableSortingType } from '@elastic/eui/src/components/basic_table/table_types'; import { MONITOR_HISTORY_ROUTE, MONITOR_TYPES } from '../../../../../../common/constants'; -import { getTestRunDetailLink, TestDetailsLink } from '../../common/links/test_details_link'; +import { + getTestRunDetailRelativeLink, + TestDetailsLink, +} from '../../common/links/test_details_link'; import { ConfigKey, DataStream, Ping } from '../../../../../../common/runtime_types'; import { formatTestDuration } from '../../../utils/monitor_test_result/test_time_formats'; import { useGetUrlParams } from '../../../hooks'; @@ -166,7 +169,7 @@ export const TestRunsTable = ({ !targetElem.parentElement?.classList.contains('euiLink') ) { history.push( - getTestRunDetailLink({ + getTestRunDetailRelativeLink({ monitorId, checkGroup: item.monitor.check_group, locationId: selectedLocation?.id, diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/test_run_details/components/step_info.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/test_run_details/components/step_info.tsx new file mode 100644 index 0000000000000..74e5da6a47d6d --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/test_run_details/components/step_info.tsx @@ -0,0 +1,93 @@ +/* + * 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 React from 'react'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiLoadingContent, + EuiSpacer, + EuiText, + EuiTitle, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { useParams } from 'react-router-dom'; +import { parseBadgeStatus, StatusBadge } from '../../common/monitor_test_result/status_badge'; +import { formatTestDuration } from '../../../utils/monitor_test_result/test_time_formats'; +import { ErrorDetailsButton } from '../../common/links/error_details_link'; +import { StepDetailsLinkIcon } from '../../common/links/step_details_link'; +import { JourneyStep } from '../../../../../../common/runtime_types'; + +export const StepMetaInfo = ({ + step, + stepIndex, + stateId, +}: { + step?: JourneyStep; + stepIndex: number; + stateId?: string; +}) => { + const { checkGroupId, monitorId } = useParams<{ checkGroupId: string; monitorId: string }>(); + + if (!step) { + return ( + + + + ); + } + + const isFailed = step.synthetics.step?.status === 'failed'; + + return ( + + +

    {STEP_NAME}

    +
    + {step?.synthetics.step?.name} + + + + + + + {AFTER_LABEL} + {formatTestDuration(step?.synthetics.step?.duration.us)} + + + + + {isFailed && stateId && ( + + + + )} + + + + +
    + ); +}; + +const STEP_NAME = i18n.translate('xpack.synthetics.testDetails.stepName', { + defaultMessage: 'Step name', +}); + +const AFTER_LABEL = i18n.translate('xpack.synthetics.testDetails.after', { + defaultMessage: 'After ', +}); + +const VIEW_PERFORMANCE = i18n.translate('xpack.synthetics.monitor.step.viewPerformanceBreakdown', { + defaultMessage: 'View performance breakdown', +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/test_run_details/step_screenshot_details.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/test_run_details/step_screenshot_details.tsx index 1bbf20c7d5ccb..50d799d6b2863 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/test_run_details/step_screenshot_details.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/test_run_details/step_screenshot_details.tsx @@ -10,12 +10,15 @@ import React from 'react'; import { useParams } from 'react-router-dom'; import { JourneyStep } from '../../../../../common/runtime_types'; import { JourneyStepScreenshotContainer } from '../common/screenshot/journey_step_screenshot_container'; +import { StepMetaInfo } from './components/step_info'; export const StepScreenshotDetails = ({ stepIndex, step, + stateId, }: { stepIndex: number; + stateId?: string; step?: JourneyStep; }) => { const { checkGroupId } = useParams<{ checkGroupId: string }>(); @@ -23,7 +26,7 @@ export const StepScreenshotDetails = ({ return ( - + - {/* TODO: add image details*/} + ); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/test_run_details/test_run_details.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/test_run_details/test_run_details.tsx index 446857ca9b779..7f1bb3be1ab0a 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/test_run_details/test_run_details.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/test_run_details/test_run_details.tsx @@ -38,6 +38,8 @@ export const TestRunDetails = () => { const { monitorId } = useParams<{ monitorId: string }>(); const selectedLocation = useSelectedLocation(); + const stateId = stepsData?.details?.summary?.state?.id; + return ( <> @@ -72,7 +74,7 @@ export const TestRunDetails = () => {
    - + diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/browser_journey/api.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/browser_journey/api.ts index e0a8068e1d460..6759bee3b1fe3 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/browser_journey/api.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/browser_journey/api.ts @@ -17,7 +17,7 @@ import { Ping, PingType, } from '../../../../../common/runtime_types'; -import { API_URLS } from '../../../../../common/constants'; +import { API_URLS, SYNTHETICS_API_URLS } from '../../../../../common/constants'; export interface FetchJourneyStepsParams { checkGroup: string; @@ -34,7 +34,7 @@ export async function fetchBrowserJourney( params: FetchJourneyStepsParams ): Promise { return apiService.get( - API_URLS.JOURNEY.replace('{checkGroup}', params.checkGroup), + SYNTHETICS_API_URLS.JOURNEY.replace('{checkGroup}', params.checkGroup), { syntheticEventTypes: params.syntheticEventTypes }, SyntheticsJourneyApiResponseType ); diff --git a/x-pack/plugins/synthetics/server/legacy_uptime/lib/lib.ts b/x-pack/plugins/synthetics/server/legacy_uptime/lib/lib.ts index de76507c330d5..c77f75dae0eaa 100644 --- a/x-pack/plugins/synthetics/server/legacy_uptime/lib/lib.ts +++ b/x-pack/plugins/synthetics/server/legacy_uptime/lib/lib.ts @@ -186,6 +186,10 @@ export class UptimeEsClient { } } +export function createEsParams(params: T): T { + return params; +} + function getInspectEnabled(uiSettings?: CoreRequestHandlerContext['uiSettings']) { if (!uiSettings) { return false; diff --git a/x-pack/plugins/synthetics/server/queries/get_journey_details.ts b/x-pack/plugins/synthetics/server/queries/get_journey_details.ts new file mode 100644 index 0000000000000..bacc3cf64ae48 --- /dev/null +++ b/x-pack/plugins/synthetics/server/queries/get_journey_details.ts @@ -0,0 +1,172 @@ +/* + * 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 { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { JourneyStep, Ping, SyntheticsJourneyApiResponse } from '../../common/runtime_types'; +import { UMElasticsearchQueryFn } from '../legacy_uptime/lib/adapters'; +import { createEsParams } from '../legacy_uptime/lib/lib'; + +export interface GetJourneyDetails { + checkGroup: string; +} + +type DocumentSource = (Ping & { '@timestamp': string }) | JourneyStep; + +export const getJourneyDetails: UMElasticsearchQueryFn< + GetJourneyDetails, + SyntheticsJourneyApiResponse['details'] +> = async ({ uptimeEsClient, checkGroup }) => { + const params = createEsParams({ + body: { + query: { + bool: { + filter: [ + { + term: { + 'monitor.check_group': checkGroup, + }, + }, + { + terms: { + 'synthetics.type': ['journey/start', 'heartbeat/summary'], + }, + }, + ], + }, + }, + size: 2, + }, + }); + + const { body: thisJourney } = await uptimeEsClient.search( + params, + 'getJourneyDetailsCurrentJourney' + ); + + const journeyStart = thisJourney.hits.hits.find( + (hit) => hit._source.synthetics?.type === 'journey/start' + ); + + if (journeyStart) { + const { _id, _source } = journeyStart; + const thisJourneySource = Object.assign({ _id }, _source) as JourneyStep; + + const baseSiblingParams = createEsParams({ + body: { + query: { + bool: { + filter: [ + { + term: { + 'monitor.id': thisJourneySource.monitor.id, + }, + }, + { + term: { + 'synthetics.type': 'journey/start', + }, + }, + ] as QueryDslQueryContainer[], + }, + }, + _source: ['@timestamp', 'monitor.check_group'], + size: 1, + }, + }); + + const previousParams = createEsParams({ + body: { + ...baseSiblingParams.body, + query: { + bool: { + filter: [ + ...baseSiblingParams.body.query.bool.filter, + { + range: { + '@timestamp': { + lt: thisJourneySource['@timestamp'], + }, + }, + }, + ], + }, + }, + sort: [{ '@timestamp': { order: 'desc' as const } }], + }, + }); + + const nextParams = createEsParams({ + body: { + ...baseSiblingParams.body, + query: { + bool: { + filter: [ + ...baseSiblingParams.body.query.bool.filter, + { + range: { + '@timestamp': { + gt: thisJourneySource['@timestamp'], + }, + }, + }, + ], + }, + }, + sort: [{ '@timestamp': { order: 'asc' as const } }], + }, + }); + + const [previousJourneyPromise, nextJourneyPromise] = await Promise.all([ + uptimeEsClient.search( + previousParams, + 'getJourneyDetailsPreviousJourney' + ), + uptimeEsClient.search( + nextParams, + 'getJourneyDetailsNextJourney' + ), + ]); + + const { body: previousJourneyResult } = previousJourneyPromise; + const { body: nextJourneyResult } = nextJourneyPromise; + + const previousJourney = + previousJourneyResult?.hits?.hits.length > 0 ? previousJourneyResult?.hits?.hits[0] : null; + const nextJourney = + nextJourneyResult?.hits?.hits.length > 0 ? nextJourneyResult?.hits?.hits[0] : null; + + const summaryPing = thisJourney.hits.hits.find( + ({ _source: summarySource }) => summarySource.synthetics?.type === 'heartbeat/summary' + )?._source; + + return { + timestamp: thisJourneySource['@timestamp'], + journey: thisJourneySource, + ...(summaryPing && 'state' in summaryPing && summaryPing.state + ? { + summary: { + state: summaryPing.state, + }, + } + : {}), + previous: previousJourney + ? { + checkGroup: previousJourney._source.monitor.check_group, + timestamp: previousJourney._source['@timestamp'], + } + : undefined, + next: nextJourney + ? { + checkGroup: nextJourney._source.monitor.check_group, + timestamp: nextJourney._source['@timestamp'], + } + : undefined, + }; + } else { + return null; + } +}; diff --git a/x-pack/plugins/synthetics/server/routes/index.ts b/x-pack/plugins/synthetics/server/routes/index.ts index a0583bd565848..5312074520ac9 100644 --- a/x-pack/plugins/synthetics/server/routes/index.ts +++ b/x-pack/plugins/synthetics/server/routes/index.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { createJourneyRoute } from './pings/journeys'; import { updateDefaultAlertingRoute } from './default_alerts/update_default_alert'; import { syncParamsSyntheticsParamsRoute } from './settings/sync_global_params'; import { editSyntheticsParamsRoute } from './settings/edit_param'; @@ -75,6 +76,7 @@ export const syntheticsAppRestApiRoutes: SyntheticsRestApiRouteFactory[] = [ enableDefaultAlertingRoute, getDefaultAlertingRoute, updateDefaultAlertingRoute, + createJourneyRoute, ]; export const syntheticsAppStreamingApiRoutes: SyntheticsStreamingRouteFactory[] = [ diff --git a/x-pack/plugins/synthetics/server/routes/pings/journeys.ts b/x-pack/plugins/synthetics/server/routes/pings/journeys.ts new file mode 100644 index 0000000000000..9ef10fe6bebb2 --- /dev/null +++ b/x-pack/plugins/synthetics/server/routes/pings/journeys.ts @@ -0,0 +1,80 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; +import { API_URLS, SYNTHETICS_API_URLS } from '../../../common/constants'; +import { UMServerLibs } from '../../legacy_uptime/uptime_server'; +import { UMRestApiRouteFactory } from '../../legacy_uptime/routes/types'; +import { getJourneyDetails } from '../../queries/get_journey_details'; + +export const createJourneyRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ + method: 'GET', + path: SYNTHETICS_API_URLS.JOURNEY, + validate: { + params: schema.object({ + checkGroup: schema.string(), + }), + query: schema.object({ + // provides a filter for the types of synthetic events to include + // when fetching a journey's data + syntheticEventTypes: schema.maybe( + schema.oneOf([schema.arrayOf(schema.string()), schema.string()]) + ), + }), + }, + handler: async ({ uptimeEsClient, request, response }): Promise => { + const { checkGroup } = request.params; + const { syntheticEventTypes } = request.query; + + try { + const [result, details] = await Promise.all([ + await libs.requests.getJourneySteps({ + uptimeEsClient, + checkGroup, + syntheticEventTypes, + }), + await getJourneyDetails({ + uptimeEsClient, + checkGroup, + }), + ]); + + return { + checkGroup, + steps: result, + details, + }; + } catch (e: unknown) { + return response.custom({ statusCode: 500, body: { message: e } }); + } + }, +}); + +export const createJourneyFailedStepsRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ + method: 'GET', + path: API_URLS.JOURNEY_FAILED_STEPS, + validate: { + query: schema.object({ + checkGroups: schema.arrayOf(schema.string()), + }), + }, + handler: async ({ uptimeEsClient, request, response }): Promise => { + const { checkGroups } = request.query; + try { + const result = await libs.requests.getJourneyFailedSteps({ + uptimeEsClient, + checkGroups, + }); + return { + checkGroups, + steps: result, + }; + } catch (e) { + return response.customError({ statusCode: 500, body: e }); + } + }, +}); From 7769bb54f7db6f2d38b345aca393d6124e03358d Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 18 Jan 2023 08:04:06 -0700 Subject: [PATCH 44/44] [maps] clean-up history injection (#148644) This PR does some tech debt clean-up on how history is used in maps application. Existing way exported a function goToSpecifiedPath. This PR removes this function and instead passes history as an argument to where its needed. Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/maps/public/render_app.tsx | 6 +----- .../public/routes/list_page/load_list_and_render.tsx | 12 +++++++++--- .../maps/public/routes/list_page/maps_list_view.tsx | 11 +++++++---- .../maps/public/routes/map_page/map_app/map_app.tsx | 10 +++++----- .../plugins/maps/public/routes/map_page/map_page.tsx | 4 ++-- .../map_page/saved_map/get_breadcrumbs.test.tsx | 8 ++++++++ .../routes/map_page/saved_map/get_breadcrumbs.tsx | 8 +++++--- .../public/routes/map_page/saved_map/saved_map.ts | 11 +++++++---- .../maps/public/routes/map_page/top_nav_config.tsx | 5 +++++ 9 files changed, 49 insertions(+), 26 deletions(-) diff --git a/x-pack/plugins/maps/public/render_app.tsx b/x-pack/plugins/maps/public/render_app.tsx index 23244df45b9b5..d8112b696d24b 100644 --- a/x-pack/plugins/maps/public/render_app.tsx +++ b/x-pack/plugins/maps/public/render_app.tsx @@ -28,8 +28,6 @@ import { MapByValueInput, MapByReferenceInput } from './embeddable/types'; import { APP_ID } from '../common/constants'; import { registerLayerWizards } from './classes/layers/wizards/load_layer_wizards'; -export let goToSpecifiedPath: (path: string) => void; - function setAppChrome() { if (!getMapsCapabilities().save) { getCoreChrome().setBadge({ @@ -73,8 +71,6 @@ export async function renderApp( AppUsageTracker: React.FC; } ) { - goToSpecifiedPath = (path) => history.push(path); - const stateTransfer = getEmbeddableService().getStateTransfer(); registerLayerWizards(); @@ -137,7 +133,7 @@ export async function renderApp( const newPath = hash.substr(1); return ; } else if (pathname === '/' || pathname === '') { - return ; + return ; } else { return ; } diff --git a/x-pack/plugins/maps/public/routes/list_page/load_list_and_render.tsx b/x-pack/plugins/maps/public/routes/list_page/load_list_and_render.tsx index bc81924a1f1cd..62403cd4db327 100644 --- a/x-pack/plugins/maps/public/routes/list_page/load_list_and_render.tsx +++ b/x-pack/plugins/maps/public/routes/list_page/load_list_and_render.tsx @@ -5,15 +5,21 @@ * 2.0. */ -import React from 'react'; +import React, { Component } from 'react'; import { i18n } from '@kbn/i18n'; import { Redirect } from 'react-router-dom'; import { EmbeddableStateTransfer } from '@kbn/embeddable-plugin/public'; +import { ScopedHistory } from '@kbn/core/public'; import { getSavedObjectsClient, getToasts } from '../../kibana_services'; import { MapsListView } from './maps_list_view'; import { APP_ID, MAP_SAVED_OBJECT_TYPE } from '../../../common/constants'; -export class LoadListAndRender extends React.Component<{ stateTransfer: EmbeddableStateTransfer }> { +interface Props { + history: ScopedHistory; + stateTransfer: EmbeddableStateTransfer; +} + +export class LoadListAndRender extends Component { _isMounted: boolean = false; state = { mapsLoaded: false, @@ -57,7 +63,7 @@ export class LoadListAndRender extends React.Component<{ stateTransfer: Embeddab const { mapsLoaded, hasSavedMaps } = this.state; if (mapsLoaded) { - return hasSavedMaps ? : ; + return hasSavedMaps ? : ; } else { return null; } diff --git a/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx b/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx index 1506a2569c273..3dab6db00885d 100644 --- a/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx +++ b/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx @@ -7,13 +7,12 @@ import React from 'react'; import { SavedObjectReference } from '@kbn/core/types'; -import type { SavedObjectsFindOptionsReference } from '@kbn/core/public'; +import type { SavedObjectsFindOptionsReference, ScopedHistory } from '@kbn/core/public'; import { METRIC_TYPE } from '@kbn/analytics'; import { i18n } from '@kbn/i18n'; import { TableListView } from '@kbn/content-management-table-list'; import type { UserContentCommonSchema } from '@kbn/content-management-table-list'; import { SimpleSavedObject } from '@kbn/core-saved-objects-api-browser'; -import { goToSpecifiedPath } from '../../render_app'; import { APP_ID, getEditPath, MAP_PATH, MAP_SAVED_OBJECT_TYPE } from '../../../common/constants'; import { getMapsCapabilities, @@ -100,7 +99,11 @@ async function deleteMaps(items: object[]) { await Promise.all(deletions); } -export function MapsListView() { +interface Props { + history: ScopedHistory; +} + +export function MapsListView(props: Props) { getExecutionContext().set({ type: 'application', page: 'list', @@ -131,7 +134,7 @@ export function MapsListView() { defaultMessage: 'maps', })} tableListTitle={getAppTitle()} - onClickTitle={({ id }) => goToSpecifiedPath(getEditPath(id))} + onClickTitle={({ id }) => props.history.push(getEditPath(id))} /> ); } diff --git a/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx b/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx index fffb12130a05d..bf8963de0461d 100644 --- a/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx +++ b/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx @@ -9,7 +9,7 @@ import React from 'react'; import _ from 'lodash'; import { finalize, switchMap, tap } from 'rxjs/operators'; import { i18n } from '@kbn/i18n'; -import { AppLeaveAction, AppMountParameters } from '@kbn/core/public'; +import { AppLeaveAction, AppMountParameters, ScopedHistory } from '@kbn/core/public'; import { Adapters } from '@kbn/embeddable-plugin/public'; import { Subscription } from 'rxjs'; import { type Filter, FilterStateStore, type Query, type TimeRange } from '@kbn/es-query'; @@ -42,7 +42,6 @@ import { AppStateManager, startAppStateSyncing } from '../url_state'; import { MapContainer } from '../../../connected_components/map_container'; import { getIndexPatternsFromIds } from '../../../index_pattern_util'; import { getTopNavConfig } from '../top_nav_config'; -import { goToSpecifiedPath } from '../../../render_app'; import { getEditPath, getFullPath, APP_ID } from '../../../../common/constants'; import { getMapEmbeddableDisplayName } from '../../../../common/i18n_getters'; import { @@ -84,7 +83,7 @@ export interface Props { isSaveDisabled: boolean; query: Query | undefined; setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; - history: AppMountParameters['history']; + history: ScopedHistory; } export interface State { @@ -397,7 +396,7 @@ export class MapApp extends React.Component { }), text: `${err.message}`, }); - goToSpecifiedPath('/'); + this.props.history.push('/'); } return; } @@ -420,7 +419,7 @@ export class MapApp extends React.Component { return; } - this.props.savedMap.setBreadcrumbs(); + this.props.savedMap.setBreadcrumbs(this.props.history); getCoreChrome().docTitle.change(this.props.savedMap.getTitle()); const savedObjectId = this.props.savedMap.getSavedObjectId(); if (savedObjectId) { @@ -457,6 +456,7 @@ export class MapApp extends React.Component { enableFullScreen: this.props.enableFullScreen, openMapSettings: this.props.openMapSettings, inspectorAdapters: this.props.inspectorAdapters, + history: this.props.history, }); const { TopNavMenu } = getNavigation().ui; diff --git a/x-pack/plugins/maps/public/routes/map_page/map_page.tsx b/x-pack/plugins/maps/public/routes/map_page/map_page.tsx index 703e60638649e..e3a2af0971355 100644 --- a/x-pack/plugins/maps/public/routes/map_page/map_page.tsx +++ b/x-pack/plugins/maps/public/routes/map_page/map_page.tsx @@ -7,7 +7,7 @@ import React, { Component } from 'react'; import { Provider } from 'react-redux'; -import type { AppMountParameters } from '@kbn/core/public'; +import type { AppMountParameters, ScopedHistory } from '@kbn/core/public'; import type { EmbeddableStateTransfer } from '@kbn/embeddable-plugin/public'; import { MapApp } from './map_app'; import { @@ -25,7 +25,7 @@ interface Props { stateTransfer: EmbeddableStateTransfer; originatingApp?: string; originatingPath?: string; - history: AppMountParameters['history']; + history: ScopedHistory; } interface State { diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/get_breadcrumbs.test.tsx b/x-pack/plugins/maps/public/routes/map_page/saved_map/get_breadcrumbs.test.tsx index 639167eba0e71..a04583270030b 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/get_breadcrumbs.test.tsx +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/get_breadcrumbs.test.tsx @@ -6,6 +6,7 @@ */ import { getBreadcrumbs } from './get_breadcrumbs'; +import { ScopedHistory } from '@kbn/core/public'; jest.mock('../../../kibana_services', () => {}); jest.mock('../../../render_app', () => {}); @@ -14,11 +15,16 @@ const getHasUnsavedChanges = () => { return false; }; +const mockHistory = { + push: () => {}, +} as unknown as ScopedHistory; + test('should get breadcrumbs "Maps / mymap"', () => { const breadcrumbs = getBreadcrumbs({ pageTitle: 'mymap', getHasUnsavedChanges, isByValue: false, + history: mockHistory, }); expect(breadcrumbs.length).toBe(2); expect(breadcrumbs[0].text).toBe('Maps'); @@ -34,6 +40,7 @@ test('should get breadcrumbs "Dashboard / mymap" with originatingApp and by valu getAppNameFromId: (appId) => { return 'Dashboard'; }, + history: mockHistory, }); expect(breadcrumbs.length).toBe(2); expect(breadcrumbs[0].text).toBe('Dashboard'); @@ -49,6 +56,7 @@ test('should get breadcrumbs "Dashboard / Maps / mymap" with originatingApp and getAppNameFromId: (appId) => { return 'Dashboard'; }, + history: mockHistory, }); expect(breadcrumbs.length).toBe(3); expect(breadcrumbs[0].text).toBe('Dashboard'); diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/get_breadcrumbs.tsx b/x-pack/plugins/maps/public/routes/map_page/saved_map/get_breadcrumbs.tsx index 2d1246c40b2e1..ca3022043cd9f 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/get_breadcrumbs.tsx +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/get_breadcrumbs.tsx @@ -6,8 +6,8 @@ */ import { i18n } from '@kbn/i18n'; +import { ScopedHistory } from '@kbn/core/public'; import { getCoreOverlays, getNavigateToApp } from '../../../kibana_services'; -import { goToSpecifiedPath } from '../../../render_app'; import { getAppTitle } from '../../../../common/i18n_getters'; export const unsavedChangesWarning = i18n.translate( @@ -27,12 +27,14 @@ export function getBreadcrumbs({ getHasUnsavedChanges, originatingApp, getAppNameFromId, + history, }: { pageTitle: string; isByValue: boolean; getHasUnsavedChanges: () => boolean; originatingApp?: string; getAppNameFromId?: (id: string) => string | undefined; + history: ScopedHistory; }) { const breadcrumbs = []; @@ -55,10 +57,10 @@ export function getBreadcrumbs({ 'data-test-subj': 'appLeaveConfirmModal', }); if (confirmed) { - goToSpecifiedPath('/'); + history.push('/'); } } else { - goToSpecifiedPath('/'); + history.push('/'); } }, }); diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts b/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts index e7adcd0795efb..30ce717b014dc 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts @@ -9,6 +9,7 @@ import _ from 'lodash'; import { METRIC_TYPE } from '@kbn/analytics'; import { i18n } from '@kbn/i18n'; import { EmbeddableStateTransfer } from '@kbn/embeddable-plugin/public'; +import { ScopedHistory } from '@kbn/core/public'; import { OnSaveProps } from '@kbn/saved-objects-plugin/public'; import { MapSavedObjectAttributes } from '../../../../common/map_saved_object_type'; import { APP_ID, MAP_PATH, MAP_SAVED_OBJECT_TYPE } from '../../../../common/constants'; @@ -45,7 +46,6 @@ import { getTimeFilter, getUsageCollection, } from '../../../kibana_services'; -import { goToSpecifiedPath } from '../../../render_app'; import { LayerDescriptor } from '../../../../common/descriptor_types'; import { copyPersistentState } from '../../../reducers/copy_persistent_state'; import { getBreadcrumbs } from './get_breadcrumbs'; @@ -326,7 +326,7 @@ export class SavedMap { } } - setBreadcrumbs() { + setBreadcrumbs(history: ScopedHistory) { if (!this._attributes) { throw new Error('Invalid usage, must await whenReady before calling hasUnsavedChanges'); } @@ -337,6 +337,7 @@ export class SavedMap { getHasUnsavedChanges: this.hasUnsavedChanges, originatingApp: this._originatingApp, getAppNameFromId: this._getStateTransfer().getAppNameFromId, + history, }); getCoreChrome().setBreadcrumbs(breadcrumbs); } @@ -433,11 +434,13 @@ export class SavedMap { newTags, saveByReference, dashboardId, + history, }: OnSaveProps & { returnToOrigin?: boolean; newTags?: string[]; saveByReference: boolean; dashboardId?: string | null; + history: ScopedHistory; }) { if (!this._attributes) { throw new Error('Invalid usage, must await whenReady before calling save'); @@ -525,8 +528,8 @@ export class SavedMap { }); getCoreChrome().docTitle.change(newTitle); - this.setBreadcrumbs(); - goToSpecifiedPath(`/${MAP_PATH}/${this.getSavedObjectId()}${window.location.hash}`); + this.setBreadcrumbs(history); + history.push(`/${MAP_PATH}/${this.getSavedObjectId()}${window.location.hash}`); if (this._onSaveCallback) { this._onSaveCallback(); diff --git a/x-pack/plugins/maps/public/routes/map_page/top_nav_config.tsx b/x-pack/plugins/maps/public/routes/map_page/top_nav_config.tsx index 2032d78ab46bc..bf417e37aef56 100644 --- a/x-pack/plugins/maps/public/routes/map_page/top_nav_config.tsx +++ b/x-pack/plugins/maps/public/routes/map_page/top_nav_config.tsx @@ -18,6 +18,7 @@ import { LazySavedObjectSaveModalDashboard, withSuspense, } from '@kbn/presentation-util-plugin/public'; +import { ScopedHistory } from '@kbn/core/public'; import { getNavigateToApp, getMapsCapabilities, @@ -42,6 +43,7 @@ export function getTopNavConfig({ enableFullScreen, openMapSettings, inspectorAdapters, + history, }: { savedMap: SavedMap; isOpenSettingsDisabled: boolean; @@ -49,6 +51,7 @@ export function getTopNavConfig({ enableFullScreen: () => void; openMapSettings: () => void; inspectorAdapters: Adapters; + history: ScopedHistory; }) { const topNavConfigs = []; @@ -197,6 +200,7 @@ export function getTopNavConfig({ ...props, newTags: selectedTags, saveByReference: props.addToLibrary, + history, }); // showSaveModal wrapper requires onSave to return an object with an id to close the modal after successful save return { id: 'id' }; @@ -266,6 +270,7 @@ export function getTopNavConfig({ returnToOrigin: true, onTitleDuplicate: () => {}, saveByReference: !savedMap.isByValue(), + history, }); }, testId: 'mapSaveAndReturnButton',